使用Canvas实现动画效果(性能优化)

demo地址:http://demo.519.pw/games/

这里我们使用Canvas开发这个游戏,而不是采用传统的DOM方式实现,虽然这个简单的游戏使用DOM也可以实现(甚至有可能更容易点)。但是Canvas可以更加方便的控制图片,功能更更加强大,因为你可以完全按照自己的想法进行绘制和操作图像。

Canvas是HTML5中新加入的标签。它定义了一个图形,可以是图表或任何内容,但是它只是一个容器,你必须使用JavaScript来进行绘制图形。Canvas并不是为动画准备的,但是你可以使用它来实现动画效果。

其实使用Canvas中的动画实现某种程度也利用了同样的思想。快速的定时的改变所绘制的图形的位置。当然Canvas上所绘制的图形不会自动消失,如果你不断的画图形会不断的重复出现在画布中,所以你需要在重绘之前清除画布,这样你得到的才是动画而不是动画的轨迹。

JavaScript中没有诸如sleep等阻塞的方法,所以我们需要使用setTimeout或setInterval来实现定时执行的功能。大部分现代浏览器中提供了一个新的方法requestAnimationFrame来代替普通的定时器,这是由FireFox首先实现的,虽然目前还不是标准,但是大部分现代浏览器中已经支持这个方法,你可能需要使用不同的前缀调用它,如:mozRequestAnimationFrame或webkitRequestAnimationFrame。这个方法类似setTimeout,它由浏览器自行判断执行的时机,当页面不可见时它会自动降频,以达到节约资源的目的。它是你实现动画的最佳选择。它的执行频率大于是每秒60次,因为这是浏览器刷新的极限,如果再高对浏览器来说就没有意义了。当然对于不支持的浏览器我们可以使用setTimeout或setInterval来代替,相信你可以很容易的实现类似功能。下面是一个兼容的写法:

window.requestAnimFrame = (function() {
    return window.requestAnimationFrame
            || window.webkitRequestAnimationFrame
            || window.mozRequestAnimationFrame
            || window.oRequestAnimationFrame
            || window.msRequestAnimationFrame || function() {
                //return setTimeout(arguments[0], 1000 / 60);
                return -1;
            } // return -1 if unsupported
})();

window.cancelRequestAnimFrame = (function() {
    return window.cancelAnimationFrame
            || window.webkitCancelRequestAnimationFrame
            || window.mozCancelRequestAnimationFrame
            || window.oCancelRequestAnimationFrame
            || window.msCancelRequestAnimationFrame || function() {
                return -1;
            } // return -1 if unsupported
})();

当然你还要熟悉一下Canvas绘图的API。

首先你需要获取一个画布的对象,然后通过画布对象的getContext()方法获取一个绘图上下文。这个方法接受一个字符串参数"2d",这是目前你所能用的,当然还有其他的模式,比如WebGL,虽然已经被Chrome和FireFox所支持,但是MS的IE浏览器应该是不会支持了。通过这个绘图上下文你可以画线也可以画图形,可以描边路径也可以填充它,还可以直接绘制图片,或者直接操作图片数据等等。