深入了解Canvas标签(7)——基本动画

来源:互联网 发布:linux创建文件夹 权限 编辑:程序博客网 时间:2024/05/23 15:43

由于我们是用脚本去操控 canvas 对象,这样要实现一些交互动画也是相当容易的。只不过,canvas 从来都不是专门为动画而设计的(不像 Flash),难免会有些限制。
可能最大的限制就是图像一旦绘制出来,它就是一直保持那样了。如果需要移动它,我们不得不对所有东西(包括之前的)进行重绘。重绘是相当费时的,而且性能很依赖于电脑的速度。(文/鬼武者)

基本动画的步骤


画一帧,你需要以下一些步骤:
清空 canvas
除非接下来要画的内容会完全充满 canvas (例如背景图),否则你需要清空所有。最简单的做法就是用 clearRect 方法。
保存 canvas 状态
如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。
绘制动画图形
这一步才是重绘动画帧。
恢复 canvas 状态
如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。

操控动画

在 canvas 上绘制内容是用 canvas 提供的或者自定义的方法,而通常,我们仅仅在脚本执行结束后才能看见结果,比如说,在 for 循环里面做完成动画是不太可能的。
我们需要一些可以定时的执行重绘的方法。有两种方法可以实现这样的动画操控。首先可以通过 setInterval 和 setTimeout 方法来控制在设定的时间点上执行重绘。

  1. setInterval(animateShape,500);
  2. setTimeout(animateShape,500);
复制代码

如果你不需要任何交互操作,用 setInterval 方法定时执行重绘是最适合的了。在上面的例子(leegorous不见了?)里 animateShape 方法每半秒执行一次。setTimeout 方法只会在预设时间点上执行操作。

第二个方法,我们可以利用用户输入来实现操控。如果需要做一个游戏,我们可以通过监听用户交互过程中触发的事件(如 keyboard,mouse)来控制动画效果。
下面的例子,我还使用第一种方式实现动画效果。页面底部有些链接,那些是应用第二种方法的例子。

动画例子 1
这个例子里面,我会让一个小型的太阳系模拟系统动起来。

  1. var sun = new Image();
  2. var moon = new Image();
  3. var earth = new Image();
  4. function init(){
  5.   sun.src = 'images/sun.png';
  6.   moon.src = 'images/moon.png';
  7.   earth.src = 'images/earth.png';
  8.   setInterval(draw,100);
  9. }
  10. function draw() {
  11.   var ctx = document.getElementById('canvas').getContext('2d');
  12.   ctx.globalCompositeOperation = 'destination-over';
  13.   ctx.clearRect(0,0,300,300); // clear canvas
  14.   ctx.fillStyle = 'rgba(0,0,0,0.4)';
  15.   ctx.strokeStyle = 'rgba(0,153,255,0.4)';
  16.   ctx.save();
  17.   ctx.translate(150,150);
  18.   // Earth
  19.   var time = new Date();
  20.   ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
  21.   ctx.translate(105,0);
  22.   ctx.fillRect(0,-12,50,24); // Shadow
  23.   ctx.drawImage(earth,-12,-12);
  24.   // Moon
  25.   ctx.save();
  26.   ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
  27.   ctx.translate(0,28.5);
  28.   ctx.drawImage(moon,-3.5,-3.5);
  29.   ctx.restore();
  30.   ctx.restore();
  31.   ctx.beginPath();
  32.   ctx.arc(150,150,105,0,Math.PI*2,false); // Earth orbit
  33.   ctx.stroke();
  34.   ctx.drawImage(sun,0,0,300,300);
  35. }
原创粉丝点击