Christian F
Christian F

Reputation: 259

Layering Canvas on another Canvas?

Im currently doing something that goes like:

However, its a pain having to redraw the entire canvas including the non-moving PNGs.

Im wondering if it would be smarter or better to have a single canvas for the Background/hexgrid and create the PNGs on additional, small canvas elements which are then zIndex'ed on top of the Background canvas. I then could make the animations (PNGs moving) easier.

However, im running into problems in regards to actually placing the "new" canvas's at the right x/y coordinates of the Background canvas.

this.drawShipImage = function(name, id, x, y){

    var div = document.getElementById("grid");
        // initial, big canvas with background is created elsewhere but has the same width/height than "grid"

    var canvas = document.createElement("canvas");
        canvas.id = name + id;
        canvas.width = 30;
        canvas.height = 30;
        canvas.style.position = "absolute";
        canvas.style.zIndex = 1;    

    var context = canvas.getContext("2d");
        context.scale(0.75, 0.75);
        context.drawImage(ship, 0, 0);

    div.appendChild(canvas);
}

Basicly, this function has 2 important Parameters, that is the x/y Parameter where the new canvas SHOULD be drawn in context to the width/height of the Background canvas. However im unable to conclude a way to get the Image to appear at the right coordinates.

I suppose the only way it could work is adding canvas.style.margin = x/y-ish into the mix ?

Upvotes: 1

Views: 3800

Answers (2)

markE
markE

Reputation: 105015

Using a second canvas (or just an img element holding your background) might be a good solution since your background will be redrawn less frequently than your animated foreground.

This is particularly true if your device has a GPU because the background element will be cached in the GPU and will redraw very quickly as compared with the relatively slower drawings on your animating foreground canvas.

You can use the CSS position property to stack 2 elements.

  1. Wrap your 2 canvases (or canvas + img elements) in a wrapping div.
  2. Set the wrapper div's position property to relative (meaning children will be positioned relative to the wrapper instead of relative to the page).
  3. Set the 2 canvases (or canvas + img elements) position to 'absolute' (meaning they are subject to being positioned relative to the wrapper).
  4. Set the top & left properties of the child elements to 0 so they will overlap. The default top & left values are zero, so assigning them to zero is optional--but explicitly assigning them to zero is more clear.

HTML

<div id='wrapper'>
    <canvas id="canvasBottom" width=300 height=200></canvas>
    <canvas id="canvasTop" width=300 height=200></canvas>
</div>

CSS

    #wrapper{
        position:relative;
        width:300px;
        height:200px;
    }
    #canvasTop,#canvasBottom{
        position:absolute; top:0px; left:0px;
        border:1px solid green;
        width:300px;
        height:200px;
    }
    #canvasTop{
        border:1px solid red;
    }

Upvotes: 3

Torsten Barthel
Torsten Barthel

Reputation: 3458

Layer canvas elements via KineticJS

It's really easy to layer canvas elements via KineticJS from Eric Rowell. It's a very useful library to work with the HTML5 canvas element.

The lib is not maintained anymore but its very stable. Get it here: KineticJS Download

Find the reference here: KineticJS Reference

If you search a little bit on the web for examples you will clearly understand that every node in KineticJS is an own canvas element. This library relies on layering canvas elements via groups and so on.

Upvotes: 0

Related Questions