Tom Murray
Tom Murray

Reputation: 99

Canvas draw calls are rendering out of sequence

I have the following code for writing draw calls to a "back buffer" canvas, then placing those in a main canvas using drawImage. This is for optimization purposes and to ensure all images get placed in sequence.

Before placing the buffer canvas on top of the main one, I'm using fillRect to create a dark-blue background on the main canvas.

However, the blue background is rendering after the sprites. This is unexpected, as I am making its fillRect call first.

Here is my code:

render: function() {
  this.buffer.clearRect(0,0,this.w,this.h);
  this.context.fillStyle = "#000044";
  this.context.fillRect(0,0,this.w,this.h);

  for (var i in this.renderQueue) {
    for (var ii = 0; ii < this.renderQueue[i].length; ii++) {
      sprite = this.renderQueue[i][ii];

      // Draw it!
      this.buffer.fillStyle = "green";
      this.buffer.fillRect(sprite.x, sprite.y, sprite.w, sprite.h);
    }
  }

  this.context.drawImage(this.bufferCanvas,0,0);
}

This also happens when I use fillRect on the buffer canvas, instead of the main one.

Changing the globalCompositeOperation between 'source-over' and 'destination-over' (for both contexts) does nothing to change this.

Paradoxically, if I instead place the blue fillRect inside the nested for loops with the other draw calls, it works as expected...

Thanks in advance!

Addenum: Changing the composite operation does behave as expected, but not for remedying this specific issue. Sorry for the ambiguity.

Upvotes: 1

Views: 600

Answers (2)

hobberwickey
hobberwickey

Reputation: 6444

Generally speaking if you need things to be in order use an array not an object. Iterating over an object is not guaranteed to be in any particular order.

Use an array and for (var i=0; i

Upvotes: 0

Simon Sarris
Simon Sarris

Reputation: 63830

There's a lot that's suspect here.

First off double buffering a canvas does nothing but hurt performance by adding complication, all browsers do double buffering automatically, so if that's your goal here you shouldn't be drawing to a buffer.

Here's an example of why you don't need double buffering: http://jsfiddle.net/simonsarris/XzAjv/

So getting to the meat of the matter, lines of javascript inside a discrete function don't simply run out of order. Something else is wrong here.

Setting a breakpoint on the drawImage would solve this pretty much instantly, so if you aren't familiar with firebug or chrome developer tools I'd highly recommend giving them a look.

I'm guessing that the "blue" you're seeing is actually the only thing drawn to your "buffer" canvas and perhaps this.buffer is not actually the buffer context.

Another possibility is that this.w and this.h are accidentally very small, so that your initial clearRect and fillRect at the start of the method are doing nothing.

In any case speculation is nowhere near as good as opening up developer tools and actually looking at what's happening.

Upvotes: 1

Related Questions