画布动画在 FireFox 中卡顿,但在 Chrome 中完美

die*_*ego 5 html javascript firefox animation canvas

我最近开始做一些 HTML5/Canvas 的东西,并且很高兴地开展我的业务,​​在 Chrome 中测试东西,直到我决定尝试我一直在 Firefox 中工作的东西......效果不太好。

这是我正在做的事情的一个简单例子。设置基本的 requestAnimationFrame shim,主循环清除画布,然后更新和绘制我的对象。很简单,关于这些东西的例子随处可见。

function loop() {
  canvas.width = canvas.width;

  requestAnimFrame(loop);

  rR.update();
  rG.update();
  rB.update();
  rY.update();

  rR.draw();
  rG.draw(); 
  rB.draw();
  rY.draw();
}

function Rect(color, x, y, speedX, speedY) {
  this.x = x;
  this.y = y;
  this.color = color;
  this.speedX = speedX;
  this.speedY = speedY;
}

Rect.prototype.draw = function () {
  context.fillStyle = this.color;
  context.beginPath();
  context.rect(this.x, this.y, 10, 10);
  context.closePath();
  context.fill();
};

Rect.prototype.update = function () {
  if (this.x < 0 || this.x > canvas.width) this.speedX = -this.speedX;
  if (this.y < 0 || this.y > canvas.height) this.speedY = -this.speedY;

  this.x += this.speedX;
  this.y += this.speedY;
};

var rR = new Rect("#FF0000", canvas.width/2, canvas.height/2, 2, 2);
var rG = new Rect("#00FF00", canvas.width/2, canvas.height/2, -2, -2);
var rB = new Rect("#0000FF", canvas.width/2, canvas.height/2, 2, -2); 
var rY = new Rect("#FFFF00", canvas.width/2, canvas.height/2, -2, 2);
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/Polaris666/psDM9/3/

当我在 Chrome 中测试它时,它看起来很棒,但 Firefox 有很多口吃和撕裂,这似乎是一项相当简单的任务。

我发现了类似的问题,但没有一个很好的明确解决方案。这是 Firefox 的东西吗?Webkit 浏览器在这方面做得更好吗?我应该放弃它并希望它在浏览器的未来版本中得到修复吗?或者也许这是我的特殊设置?我正在使用 Windows 7 64 位和 FireFox 17.0.1。

任何帮助表示赞赏。

小智 1

@HakanEnsari 提供的解决方案似乎有效。我很好奇原因,发现这是因为他的代码版本没有清除整个画布。它仅清除各个 10x10 矩形,而不会影响画布的其余部分。

这有点深入,还有很多其他有用的画布性能技巧: http://www.html5rocks.com/en/tutorials/canvas/performance/#toc-render-diff

所以你想要这个:

  function loop() {
    // get rid of this
    //canvas.width = canvas.width; 

    requestAnimFrame(loop);
Run Code Online (Sandbox Code Playgroud)

只需清除各个矩形即可

Rect.prototype.update = function () {  
    if (this.x < 0 || this.x > canvas.width) this.speedX = -this.speedX;
    if (this.y < 0 || this.y > canvas.height) this.speedY = -this.speedY;

    // clear just the rect
    context.clearRect(this.x, this.y, 10, 10);

    this.x += this.speedX;
    this.y += this.speedY;
  };
Run Code Online (Sandbox Code Playgroud)

(调整小提琴:http://jsfiddle.net/shaunwest/B7z2d/1/