Javascript 仅当设置了新帧时才将动画绘制到画布?

Javascript 仅当设置了新帧时才将动画绘制到画布?,javascript,html,animation,canvas,requestanimationframe,Javascript,Html,Animation,Canvas,Requestanimationframe,我有一些JavaScript代码,在画布上使用基于sprite的动画,我想看看是否可以提高效率。我已经在使用requestAnimationFrame,但由于它是基于交互的,所以我也在尝试找出如何在设置新帧时使其仅绘制帧。然而,无论我尝试什么,即使动画没有运行,它仍然似乎在绘制新帧。有时修改代码似乎会增加CPU的使用率。我真的很不明白这里发生了什么 以下是原始代码: 函数画布(画布、宽度、高度、精灵url、行、列、总框架){ this.canvas=画布; 这个。宽度=宽度; 高度=高度; t

我有一些JavaScript代码,在画布上使用基于sprite的动画,我想看看是否可以提高效率。我已经在使用
requestAnimationFrame
,但由于它是基于交互的,所以我也在尝试找出如何在设置新帧时使其仅绘制帧。然而,无论我尝试什么,即使动画没有运行,它仍然似乎在绘制新帧。有时修改代码似乎会增加CPU的使用率。我真的很不明白这里发生了什么

以下是原始代码:

函数画布(画布、宽度、高度、精灵url、行、列、总框架){
this.canvas=画布;
这个。宽度=宽度;
高度=高度;
this.rows=行;
this.columns=列;
this.total_frames=总_frames;
此.frame=0;
var scope=这个,
func=函数(){
scope.onPriteSheet.call(scope);
}
加载('img','spritesheet',sprite_url,func);
};
CanvasSprite.prototype.onPriteSheet=函数(){
this.sw=this.spritesheet.width/this.columns;
this.sh=this.spritesheet.height/this.rows;
this.tick(new Date().getTime());
};
CanvasSprite.prototype.load=函数(类型、属性、url、回调){
此[prop]=document.createElement(类型);
此[prop].addEventListener('load',回调);
此[prop].src=url;
};
CanvasSprite.prototype.draw=函数(){
var relativeFrame=Math.round(this.frame*(this.total_frames-1));
var column\u frame=relativename%this.columns;
var sx=this.sw*column_frame;
var sy=this.sh*Math.floor(relativename/this.columns);
var context=this.canvas.getContext('2d');
clearRect(0,0,this.width,this.height);
context.drawImage(this.spritesheet,sx,sy,this.sw,this.sh,0,0,this.width,this.height);
};
CanvasSprite.prototype.tick=函数(时间){
var scope=这个,
func=函数(时间){
scope.draw(time | | new Date().getTime());
requestAnimationFrame(func,scope.id);
//控制台日志(“图纸”);
};
func();
};
CanvasSprite.prototype.setFrame=函数(框架){
this.frame=frame;
//this.tick(new Date().getTime());
//把勾号()放在这里实际上会使它变慢:p

};自己解决了!首先,使用
isDirty
标志,而不是尝试比较帧。然后,由于交互实际上以子帧间隔更新动画,因此将计算要绘制的实际帧的线移动到
setFrame
函数中。还移动了将动画同步到
setFrame
tick
函数,并在加载时调用该函数以从第0帧开始。这样就不会不断地传递新的日期和时间。最后,测试是否绘制新框架的条件需要位于调用draw函数的闭包中。这是因为
requestAnimationFrame
实际上比任何对画布的调用都要占用大量CPU

结果如何?不更新时无CPU使用,更新时大幅降低:)

函数画布(画布、宽度、高度、精灵url、行、列、总框架){
this.canvas=画布;
这个。宽度=宽度;
高度=高度;
this.rows=行;
this.columns=列;
this.total_frames=总_frames;
this.isDirty=true;
var scope=这个,
func=函数(){
scope.onPriteSheet.call(scope);
}
加载('img','spritesheet',sprite_url,func);
};
CanvasSprite.prototype.onPriteSheet=函数(){
this.sw=this.spritesheet.width/this.columns;
this.sh=this.spritesheet.height/this.rows;
这个.setFrame(0);
};
CanvasSprite.prototype.load=函数(类型、属性、url、回调){
此[prop]=document.createElement(类型);
此[prop].addEventListener('load',回调);
此[prop].src=url;
};
CanvasSprite.prototype.draw=function(){
var column\u frame=this.frame%this.columns;
var sx=this.sw*column_frame;
var sy=this.sh*Math.floor(this.frame/this.columns);
var context=this.canvas.getContext('2d');
clearRect(0,0,this.width,this.height);
context.drawImage(this.spritesheet,sx,sy,this.sw,this.sh,0,0,this.width,this.height);
};
CanvasSprite.prototype.tick=函数(时间){
var scope=这个,
func=函数(时间){
if(范围isDirty){
scope.draw(time | | new Date().getTime());
requestAnimationFrame(func,scope.id);
scope.isDirty=false;
//仅在新帧与旧帧不同时绘制到画布
};
};
func();
};
CanvasSprite.prototype.setFrame=函数(框架){
var tempFrame=Math.round(frame*(this.total_frames-1));;
if(tempFrame!=此.frame){
this.frame=tempFrame;
this.isDirty=true;
this.tick(new Date().getTime());
}

};自己解决了!首先,使用
isDirty
标志,而不是尝试比较帧。然后,由于交互实际上以子帧间隔更新动画,因此将计算要绘制的实际帧的线移动到
setFrame
函数中。还移动了将动画同步到
setFrame
tick
函数,并在加载时调用该函数以从第0帧开始。这样就不会不断地传递新的日期和时间。最后,测试是否绘制新框架的条件需要位于调用draw函数的闭包中。这是因为
requestAnimationFrame
实际上比任何对画布的调用都要占用大量CPU

结果如何?不更新时无CPU使用,更新时大幅降低:)

函数画布(画布、宽度、高度、精灵url、行、列、总框架){
this.canvas=画布;
这是宽度=