multiple - html5 layers demo




html5-canvas element-Multiple layers (4)

I understand that the Q does not want to use a library, but I will offer this for others coming from Google searches. @EricRowell mentioned a good plugin, but, there is also another plugin you can try, html2canvas.

In our case we are using layered transparent PNG's with z-index as a "product builder" widget. Html2canvas worked brilliantly to boil the stack down without pushing images, nor using complexities, workarounds, and the "non-responsive" canvas itself. We were not able to do this smoothly/sane with the vanilla canvas+JS.

First use z-index on absolute divs to generate layered content within a relative positioned wrapper. Then pipe the wrapper through html2canvas to get a rendered canvas, which you may leave as-is, or output as an image so that a client may save it.

Without any extension library, is it possible to have multiple layers in the same canvas element?

So if I do a clearRect on the top layer, it will not erase the bottom one?

Thanks.


I was having this same problem too, I while multiple canvas elements with position:absolute does the job, if you want to save the output into an image, that's not going to work.

So I went ahead and did a simple layering "system" to code as if each layer had its own code, but it all gets rendered into the same element.

https://github.com/federicojacobi/layeredCanvas

I intend to add extra capabilities, but for now it will do.

You can do multiple functions and call them in order to "fake" layers.


Related to this:

If you have something on your canvas and you want to draw something at the back of it - you can do it by changing the context.globalCompositeOperation setting to 'destination-over' - and then return it to 'source-over' when you're done.

var co = document.getElementById('cvs').getContext('2d');

// Draw a red square

co.fillStyle = 'red';
co.fillRect(50,50,100,100);



// Change the globalCompositeOperation to destination-over so that anything
// that is drawn on to the canvas from this point on is drawn at the back
// of whats already on the canvas

co.globalCompositeOperation = 'destination-over';



// Draw a big yellow rectangle

co.fillStyle = 'yellow';
co.fillRect(0,0,600,250);


// Now return the globalCompositeOperation to source-over and draw a
// blue rectangle

co.globalCompositeOperation = 'source-over';

co.fillStyle = 'blue';
co.fillRect(75,75,100,100);

You can create multiple canvas elements without appending them into document. These will be your layers:

Then do whatever you want with them and at the end just render their content in proper order at destination canvas using drawImage on context.

Example:

/* using canvas from DOM */
var domCanvas = document.getElementById('some-canvas');
var domContext = domCanvas.getContext('2d');
domContext.fillRect(50,50,150,50);

/* virtual canvase 1 - not appended to the DOM */
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'blue';
ctx.fillRect(50,50,150,150);

/* virtual canvase 2 - not appended to the DOM */    
var canvas2 = document.createElement('canvas')
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = 'yellow';
ctx2.fillRect(50,50,100,50)

/* render virtual canvases on DOM canvas */
domContext.drawImage(canvas, 0, 0, 200, 200);
domContext.drawImage(canvas2, 0, 0, 200, 200);

And here is some codepen: https://codepen.io/anon/pen/mQWMMW





layer