转自:http://www.cnblogs.com/dxy1982/archive/2012/03/13/2391624.html
HTML5之Canvas 2D入门5 - 事件与动画
Canvas & SVG & DOM
Canvas与SVG都是2D绘图的利器,除此之外,使用CSS、DOM也可以实现某些性状的绘制,而且在动画中,也都可以使用这些技术实现动画效果。这里就简单比较一下这些技术。
从上面看到,canvas的限制很多,那么我们为什么还要使用cavas呢?
首先,canvas是更底层的技术,你能方便的控制绘制过程,内存使用量也比较低,但是代价就是需要写更多的代码。SVG的优势在于可以利用现有的shape去绘制。CSS或者DOM动画的优势在于动画大范围的区域。
其次,如果你想去对图,图形,动态图表,视频游戏使用3D的变换时,canvas是比较好的选择。
此外还有一点要注意,canvas对2D绘图提供了直接的API支持,但是3D的API是WebGL提供的。WebGL是更底层的技术,难于使用,但是也更加强大。
事件
事件是的基础,这里也简单介绍一下canvas的事件。canvas没有定义任何新的事件,你仍然可以像以前那样去监听任何的鼠标事件。上面也说到了,canvas的内部就是一系列的像素,它们不响应任何的事件,所以浏览器不知道canvas内部是什么东西。
如果你想让内部的图形接受事件,对canvas来说几乎是不可能呢。但是幸运的是,你还是可以知道给定的点在不在当前的path中,例子如下:
检测点是否在一个图形(规则的图形,比如说自己画的按钮)中,通常的做法是比较该点的坐标与图形的各个顶点的坐标。
基本动画
动画的基本思路是用脚本去操控canvas对象,这样要实现一些交互动画也是相当容易的。只不过,canvas不是专门为动画而设计的(不像Flash),所以操作起来会有些限制。
最大的限制就是图像一旦绘制出来,它就是一直保持那样了。如果需要移动它,我们不得不重绘所有的东西。重绘是相当费时的,而且性能依赖于电脑的速度。
基本动画的步骤:
1.画一帧,需要以下一些步骤:
(1)清空 canvas
除非接下来要画的内容会完全充满 canvas(例如背景图),否则你需要清空所有。最简单的做法就是用clearRect方法。
(2)保存 canvas 状态
如果你要改变一些会改变canvas状态的设置(样式,变形之类的),又要在画每一帧之时都是原始状态的话,你需要先保存一下。
(3)绘制动画图形(animated shapes)
这一步才是重绘动画帧,一般的步骤都是去生成新图形,更新已有的图形位置,清除已经移动到canvas外面的图形,最后绘制出新的场景。
(4)恢复canvas状态
如果已经保存了canvas的状态,可以先恢复它,然后重绘下一帧。
2.按照一定的设置去计算图形的变换,重绘新的帧,画每一帧的过程是一样的。
通常有两种方式去设置重绘的频率:
(1)定时重绘
第一种方式是通过setInterval和setTimeout方法来控制在设定的时间点上执行重绘。
setInterval(animateShape,500);
setTimeout(animateShape,500);
setTimeout和setInterval的语法相同。它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将执行那段代码。
不过这两个函数还是有区别的,setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。
如果你不需要任何交互操作,用setInterval方法定时执行重绘是最适合的了。
(2)特定事件重绘
第二个方法,我们可以利用用户输入来实现操控。如果需要做一个游戏,我们可以通过监听用户交互过程中触发的事件(如document的各种keyboard,mouse事件)来控制动画效果。
下面的例子采用第一种方式模拟一个简单的下雪场景,loop方法定义了每一帧的需要进行的操作:
精灵动画
精灵动画也是动画常见的技法之一。
精灵就是一副小的图片。你可以快速的把它绘制到屏幕上。通常来说,一个精灵就是一个大图片的一部分,这部分也成为精灵片段。这个片段可能包括一个精灵的所有动作,也可能包括一个游戏中所有的角色。通过在不同的帧绘制不同的精灵,实现的动画就是精灵动画。这也是典型的翻书型的动画,大家小时候在书上肯定画过不少这种类型的动画。
为什么要使用精灵呢?
主要有下面一些优点:
1.精灵是一副小图片,所以绘制速度很快。特别是相对于比较复杂的vector。
2.重复绘制一个对象很多次时,使用精灵比较方便。比如空战游戏中的子弹,满屏幕都是,这个可以就加载一次子弹精灵,然后不断的去绘制。
3.精灵可以快速、方便的下载。只要下载一副图片,所有的精灵就都下载下来了。这比下载很多的小图片要方便,而起内存占用量也比较小。
4.耦合性比较低,容易升级精灵。因为你的代码只知道要不停的播放精灵,并不关心精灵的内容。这样后期想更换精灵形象的时候就很方便,只要把图片修改一下即可。
绘制精灵的过程很简单,前面其实已经讲过了,精灵是小的图片,直接使用绘制图片的API:context.drawImage绘制即可。
优化
我们从上面也看到了,canvas动画在每一帧都要重画,这是很耗时的。为了提升动画效率,我们需要优化绘制过程。这里总的准则就是“少画”。
canvas基本就这些内容了,Over。
实用参考:
官方参考文档以及API详细说明:http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html
权威开发入门:https://developer.mozilla.org/cn/Canvas_tutorial
API一览表:http://simon.html5.org/dump/html5-canvas-cheat-sheet.html