Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canvas animation stutters in FireFox but is perfect in Chrome

I recently got about doing some HTML5/Canvas stuff and was going about my business quite happily, testing stuff in Chrome, until I decided to try what I have been working on in Firefox... doesn't work so good.

This is a bare bones example of the kind of stuff I'm doing. Setting up the basic requestAnimationFrame shim, the main loop clears the canvas and then updates and draws my objects. Easy enough, examples about this stuff are every where to be found.

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);

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

When I test that in Chrome it looks great, but Firefox has a lot of stuttering and tearing, for what seems a rather simple task.

I have found similar questions but none with a good clear solution. Is this a Firefox thing? Are Webkit browsers just better at doing this? Should I just give up on it and hope it is fixed in future versions of the browser? Or maybe it is my particular set up? I'm using Windows 7 64bit with FireFox 17.0.1.

Any help is appreciated.

like image 966
diego Avatar asked Nov 13 '22 13:11

diego


1 Answers

The solution @HakanEnsari provided seems to work. I was curious about the reason and found that it's because his version of the code doesn't clear the entire canvas. It only clears the individual 10x10 Rects and leaves the rest of the canvas alone.

This goes into it a bit, and also has a lot of other useful canvas performance tips: http://www.html5rocks.com/en/tutorials/canvas/performance/#toc-render-diff

So you want this:

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

    requestAnimFrame(loop);

Just clear the individual rects

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;
  };

(tweaked fiddle: http://jsfiddle.net/shaunwest/B7z2d/1/)

like image 186
Shaun West Avatar answered Nov 15 '22 05:11

Shaun West