解决:简单的HTML5画布操作减慢浏览器

问题描述:

发现

解决方案:解决:简单的HTML5画布操作减慢浏览器

使用setTimeout而不是setInterval

我最近一直在使用canvas进行playind,今天开始使用setInterval来定期刷新/动画。 我很惊讶地看到这是如何沉重的CPU和减慢eveyrthing。在线看我的例子,我确定我的做法有问题。然后,我最大限度地简化了我想要做的事情(不使用图像而是使用矩形,不使用太多的对象等),但仍然遇到同样的问题。

我试图在两个矩形的顶部...所以没有什么复杂的,在所有获得白色闪光(12FPS处)...

这里是我的代码。

function Canvas(name){ 
this.ctx=document.getElementById(name).getContext('2d'); 
this.canvas=this.ctx.canvas; 
this.width=this.canvas.width; 
this.height=this.canvas.height; 
this.layers=new Array(); 

this.draw = function() { 
this.canvas.width = this.canvas.width; 
    this.ctx.beginPath(); 
    this.ctx.rect(0,0,this.width,this.height); 
    this.ctx.closePath(); 
    this.ctx.fillStyle="#eaeaea"; 
    this.ctx.fill(); 
    this.ctx.beginPath(); 
    this.ctx.rect(250,50,300,250); 
    this.ctx.closePath(); 
    this.ctx.fillStyle="#ff0000"; 
    this.ctx.fill(); 

    intensity=Math.random(); 
    this.flash(intensity); 
}; 

this.flash = function(intensity) { 
    this.ctx.globalAlpha = intensity; 
    this.ctx.beginPath(); 
    this.ctx.rect(0,0,this.width,this.height); 
    this.ctx.closePath(); 
    this.ctx.fillStyle="#fff"; 
    this.ctx.fill(); 
    this.ctx.globalAlpha = 1; 
    setInterval(this.draw.bind(this),1000); 
}; 

function initCanvas(){ 
mycanvas=new Canvas('myCanvas'); 
mycanvas.draw(); 
} 

$(document).ready(function() { 
    initCanvas(); 
}); 
+0

要将答案标记为解决方案,请单击答案旁边的勾号。 – 2012-07-17 12:21:47

关闭所有的路径,你打开:

this.draw = function() { 
    this.canvas.width = this.canvas.width; 
    this.ctx.beginPath(); 
    this.ctx.rect(0,0,this.width,this.height); 
    this.ctx.closePath(); //Closing 
    this.ctx.fillStyle="#eaeaea"; 
    this.ctx.fill(); 
    this.ctx.beginPath(); 
    this.ctx.rect(250,50,300,250); 
    this.ctx.closePath(); //Closing 
    this.ctx.fillStyle="#ff0000"; 
    this.ctx.fill(); 

    this.flash(40); 
}; 

this.flash = function(intensity) { 
    this.ctx.globalAlpha = intensity; 
    this.ctx.beginPath(); 
    this.ctx.rect(0,0,this.width,this.height); 
    this.ctx.closePath(); //Closing 
    this.ctx.fillStyle="#fff"; 
    this.ctx.fill(); 
    this.ctx.globalAlpha = 1; 
    setInterval(this.draw.bind(this),1000); 
}; 

,因为你一直在flash功能使用setInterval你已经有了一个巨大的内存泄漏。让我们来看看事件的

  • mycanvas对象创建
  • 平局()
  • 绘制调用闪烁序列
  • 闪光灯设置一个间隔调用draw每秒
  • 平局来电闪灯并设置另一个间隔
  • 过程重复,直到您有很多间隔调用draw

要解决该问题,请在flash中使用setTimeout。因此,它在一秒钟后呼叫draw,该号码呼叫flash,然后在一秒钟内再次呼叫draw。另外,1000毫秒不会给你12fps。 1000/12会。

此外,使用ctx.closePath();收你beginPath()

你开的路径也从未有}关闭Canvas功能。

这里有一个demo

+0

当然!谢谢! 我没有正确读取setInterval ... 1000只用于测试它把40现在为25fps。它工作正常。 – user1531617 2012-07-17 12:08:15

+0

@ user1531617如果解决了您的问题,请将答案标记为解决方案。 – 2012-07-17 12:09:10

我不知道这是否是相关的了,但我发现自己在一个类似的情况,想给一个更好的答案。 使用requestAnimationFrame(yourLoop),尤其是游戏,因为它速度更快,性能更好。 http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/