我只把对每一帧的渲染函数贴出来
function render(ctx){
ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height );
ctx.save(); // 第一个save()
ctx.fillStyle = "#333";
ctx.fillRect( 0, 0, ctx.canvas.width, ctx.canvas.height );
ctx.save(); // 第二个save(),后面几行代码涉及图形变换,需要保存当前绘制状态
ctx.translate( 400, 400 );
ctx.scale( searchLight.R, searchLight.R );
starPath(ctx);
ctx.fillStyle = "#FFF";
ctx.fill();
ctx.restore(); /* 绘制状态返回到图形变换之前。第一次我把clip()写在restore()的前面,没有出现剪辑效果。调整顺序后成功,我的理解是因为要将剪辑效果作用于后面的绘制。这样理解对不对? */
ctx.clip();
ctx.fillStyle = "#058";
ctx.font = " bold 80px Arial ";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText( "CANVAS", ctx.canvas.width/2, ctx.canvas.height /4 );
ctx.fillText( "CANVAS", ctx.canvas.width/2, ctx.canvas.height* 5/12 );
ctx.fillText( "CANVAS", ctx.canvas.width/2, ctx.canvas.height* 7/12 );
ctx.fillText( "CANVAS", ctx.canvas.width/2, ctx.canvas.height* 3/4 );
ctx.restore(); /* 这个restore() 对应的是第一个save()吧。之前的例子中,没有动画,好像不写这一对也不会出错。但这个例子里注释掉这一对,画面就变成静止的了。不知道是什么原因? */
}
save和restore是用于绘制环境的保存与还原,如果你不写这一对方法,你前面进行的操作(全屏先涂#333)就不会被还原,而是在原来的绘制环境(简单理解就是原图形)上进行新的操作,这样你第二次画的内容都是在原图上画的。
clip与你第一次restore的顺序没有关系,你可以把每一帧的绘画放在一个save和restore之间,最重要的是你需要在clip前调用beginpath方法,如果不调用beginpath你每次的剪切圆不会消失而是一直保持在画面上。
调用一个beginpath,closepath就可以啦。