Using Multiple HTML5 Canvases as Layers

DEMO Here’s our finished canvas with full source code.

The reasons why you would want to layer multiple canvases on top of each other are many but they all have a common root. There is a requirement in the W3C definition of the 2d context…

There is only one CanvasRenderingContext2D object per canvas, so calling the getContext() method with the 2d argument a second time must return the same object.
http://dev.w3.org/html5/2dcontext/#conformance-requirements

Having just one 2d context means that you have to keep track of everything on the context even if you only want to change part of the canvas.

An example of using layers is animation. When I was a child, I loved making animated cartoons and I learned that if I painted them on clear plastic sheets I could stack the sheets and only redraw the parts that moved. I could make an elaborate background and use it over and over instead of redrawing it for every frame. The same principle applies here to our canvases.

In this example, our three canvases have transparent areas that allow you to see what is on the canvas beneath each.

First, let’s look at our three canvases separately and then we’ll stack them on top of each other.

Our bottom layer


This text is displayed if your browser does not support HTML5 Canvas.


function draw1() {
  ctx1.clearRect(0, 0, WIDTH, HEIGHT);
  ctx1.fillStyle = "#FAF7F8";
  ctx1.beginPath();
  ctx1.rect(0,0,WIDTH,HEIGHT);
  ctx1.closePath();
  ctx1.fill();
  ctx1.fillStyle = "#444444";
  ctx1.beginPath();
  ctx1.arc(x, y, 10, 0, Math.PI*2, true);
  ctx1.closePath();
  ctx1.fill();

  if (x + dx > WIDTH || x + dx < 0)
    dx = -dx;
  if (y + dy > HEIGHT || y + dy < 0)
    dy = -dy;

  x += dx;
  y += dy;
}

The code for this animation is fully explained here. Simple Animation in the HTML5 Canvas Element

Our middle layer


This text is displayed if your browser does not support HTML5 Canvas.


function draw2() {
  ctx2.clearRect(0, 0, WIDTH, HEIGHT);
  ctx2.drawImage(city, 0, 0); 
}

We are simply drawing city.png http://html5.litten.com/layers/city.png to the canvas. The sky in this image is transparent.

Our top layer


This text is displayed if your browser does not support HTML5 Canvas.


function draw3() {
  ctx3.clearRect(0, 0, WIDTH, HEIGHT);
  ctx3.fillStyle = "#444444";
  ctx3.save();
  ctx3.translate(200,200);
  ctx3.rotate(x/20); 
  ctx3.fillRect(-15, -15, 30, 30);  
  ctx3.restore();
}

Here we transform the canvas’s coordinate system and rotate the square based on the global variable x which is used in layer 1 also. For more information on transforms with save() and restore() go here Understanding save() and restore() for the Canvas Context


Now to stack them

We use CSS to set all the canvases to an absolute position of (0,0) inside our parent DIV tag.


    position:absolute;
    left:0px;
    top:0px;

We also use CSS to set the z-index of our canvases. The z-index property specifies the stack order of an element. Items with lower z-index values go behind items with higher z-index values.


Bottom layer
    canvas id="layer1" 
    style="z-index: 1;
    
Middle layer    
    canvas id="layer2" 
    style="z-index: 2;

Top Layer    
    canvas id="layer3" 
    style="z-index: 3;      

DEMO Here's our finished canvas with full source code.

Now it doesn't matter that a canvas can only have one 2d context because we can just make multiple canvases and stack them.

If you have a question that you do not want published as a public comment, then use my contact page.

Have fun with the code as that is the easiest way to learn.

17 Replies to “Using Multiple HTML5 Canvases as Layers”

  1. Do you know whether you can superimpose a canvas (or stack of canvases) over a Google Map and draw and animate stuff over the map? Thanks for the great writeup.

  2. hello james
    i created a playing card game which uses multiple canvases.
    in the game, each object has its own canvas.
    i got the idea of using multiple canvases from this your blog post.
    tank you!

    ono
    http://onohugou.sakura.ne.jp
    *supported browsers: firefox4 and chrome10+

  3. Hi,

    Thanks for your explain on that.

    In my application, I have mousedown and mousedrag events in the bottom layer. However, these can be interrupted by the top layer. Can we eliminate the effect from top layer?

    Thanks.

  4. Hi,
    I have two canvas one for capture photo, anther for uploading a pic
    Selfie
    Upload cartoon pic

    I want to place the second canvas on the top right corner of the first canvas(the first one should be intact too)

    In my case, the canvas goes blank when i try to do the other function.

  5. Now that you know how to implement the example using a single canvas, let’s find ways to refine this type of scene and speed up the render loop. To use the layer technique, you have to identify the HTML5 canvas elements the layering needs by finding the entities’ rendering overlap.

  6. Hi thank you for this tutorial.
    I get it work i make 3 canvas layers in top of each other.
    but now how can I group those 3 layers to one canvas and download it ?

  7. Hi, thank you for this tutorial, but in this moment in concole log an error ocured: Uncaught SyntaxError: Unexpected token <. Check please, beacause don't work all examples on this page.

  8. Superb and thank U for this code and demo. wanna grab a quick tutorial this is the one !!
    U can learn in less time than searching thru a maze of tutorials 🙂

  9. I tried this for a little canvas paint program so I could track the cursor on a separate layer, but the upper canvas (wit z-index 2) never shows. I know the draw commands are executing but it seems as if the lower canvas (z-index 1) overrides them. Same thing happens when I copy your code into a file and run it. Only the bouncing ball shows up. Did Chrome (and FireFox) do something to make this from working or is there some transparency factor I am forgetting? Thanks – NHW

Leave a Reply

Your email address will not be published. Required fields are marked *