文章原创来源于:http://www.cnblogs.com/axes/p/3567364.html?utm_source=tuicool&utm_medium=referral
使用缓存
使用缓存就是用离屏canvas进行预渲染了。原理就是先绘制一个离屏canvas,然后再通过drawImage把离屏canvas画到主canvas中。把离屏canvas当成一个缓存区,需要重复绘制的画面数据进行缓存。减少调用canvas的API消耗。
例如下面的DEMO:
1、使用了缓存
2、没使用缓存
看到上面的DEMO性能明显不一样。分析一下原因:为了实现每个圈的样式,所以绘制圈圈时用了循环绘制,如果没有启用缓存,当页面的圈圈数量达到一定时,动画的每一帧就要大量调用canvas的API,要进行大量的计算,这样再好的浏览器也会被拖垮。
ctx.save();
var j=0;
ctx.lineWidth = borderWidth;
for(var i=1;i<this.r;i+=borderWidth){
ctx.beginPath();
ctx.strokeStyle = this.color[j];
ctx.arc(this.x , this.y , i , 0 , 2*Math.PI);
ctx.stroke();
j++;
}
ctx.restore();
除了创建离屏的canvas作为缓存之外,下面的代码中有一点很关键,就是要设置离屏canvas的宽度和高度,canvas生成后的默认大小是300X150,对于代码中每个缓存起来圈圈对象半径最大也就不超过80,所以300X150的大小明显会造成很多空白区域,会造成资源浪费,所以要设置一下离屏canvas的宽度和高度,让他跟缓存起来的元素大小一致,这样有利于提高动画性能。
var ball = function(x , y , vx , vy , useCache){
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.r = getZ(getRandom(20,40));
this.color = [];
this.cacheCanvas = document.createElement("canvas");
this.cacheCtx = this.cacheCanvas.getContext("2d");
this.cacheCanvas.width = 2*this.r;
this.cacheCanvas.height = 2*this.r;
var num = getZ(this.r/borderWidth);
for(var j=0;j<num;j++){
this.color.push("rgba("+getZ(getRandom(0,255))+","+getZ(getRandom(0,255))+","+getZ(getRandom(0,255))+",1)");
}
this.useCache = useCache;
if(useCache){
this.cache();
}
}
当实例化圈圈对象时,直接调用缓存方法,把复杂的圈圈直接画到圈圈对象的离屏canvas中保存起来。
cache:function(){
this.cacheCtx.save();
var j=0;
this.cacheCtx.lineWidth = borderWidth;
for(var i=1;i<this.r;i+=borderWidth){
this.cacheCtx.beginPath();
this.cacheCtx.strokeStyle = this.color[j];
this.cacheCtx.arc(this.r , this.r , i , 0 , 2*Math.PI);
this.cacheCtx.stroke();
j++;
}
this.cacheCtx.restore();
}
然后在接下来的动画中,只需要把圈圈对象的离屏canvas画到主canvas中,这样,每一帧调用的canvasAPI就只有这么一句话:
ctx.drawImage(this.cacheCanvas , this.x-this.r , this.y-this.r);