Reputation: 4340
Is it possible to combine the contents of 2 separate canvas elements into a single canvas element?
Something like an equivalent of 'Flattening' two or more layers in Photoshop...?
I can think of a round about way, but am not so sure about it. I export the contents of both the canvi (lol) in the form of .png's, and then have a third canvas element draw both images with some sort of blending algorithm (xor, blend, negative, etc.).
Upvotes: 41
Views: 49047
Reputation: 63802
Of course you can, and you don't need any funny libraries or anything, just call drawImage
with a canvas as the image.
Here is an example where I combine two canvas elements onto a third:
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
ctx.fillStyle = 'rgba(255,0,0,.4)';
ctx.fillRect(20, 20, 20, 80);
ctx.fillStyle = 'rgba(205,255,23,.4)';
ctx.fillRect(30, 30, 40, 50);
ctx.fillStyle = 'rgba(5,255,0,.4)';
ctx.fillRect(40, 50, 80, 20);
var can2 = document.getElementById('canvas2');
var ctx2 = can2.getContext('2d');
ctx2.beginPath();
ctx2.fillStyle = "pink";
ctx2.arc(50, 50, 50, 0, Math.PI * 2, 1);
ctx2.fill();
ctx2.beginPath();
ctx2.clearRect(20, 40, 60, 20);
var can3 = document.getElementById('canvas3');
var ctx3 = can3.getContext('2d');
ctx3.drawImage(can, 0, 0);
ctx3.drawImage(can2, 0, 0);
<canvas id="canvas1" width="200" height="200" style="border: 1px solid black"></canvas>
<canvas id="canvas2" width="200" height="200" style="border: 1px solid black"></canvas>
<canvas id="canvas3" width="200" height="200" style="border: 1px solid black"></canvas>
http://jsfiddle.net/bnwpS/878/
Of course you can do it with just two (one onto the other), but three makes for a better example.
You can always change the globalCompositeOperation
if you want an XOR effect or something.
Upvotes: 58
Reputation: 1958
I think you are looking for something like the pixastic library (Documentation).
Upvotes: 0
Reputation: 303136
canvas
elements do not have a background specified in CSS. This will leave them transparent.Absolutely position all your canvas
elements over top of each other. For example, wrap them all in a <div class="canvas-layers">
and then use CSS like:
/* Set to the same width/height as the canvases */
.canvas-layers { position:relative; width:400px; height:300px }
.canvas-layers canvas { position:absolute; top:0; left:0 }
Let the browser automatically perform the blending of semi-transparent areas over top of one another.
drawImage
with one canvas as the source 'image'. For example, see:globalCompositeOperation
property of the canvas context and use drawImage
with one canvas as the source. See an example here:I have created a simple, lightweight, open-source library for performing Photoshop-style blend modes from one HTML Canvas context to another: context-blender. Here's the sample usage:
// Might be an 'offscreen' canvas
var over = someCanvas.getContext('2d');
var under = anotherCanvas.getContext('2d');
over.blendOnto( under, 'screen', {destX:30,destY:15} );
See the README for more information.
Upvotes: 15
Reputation: 677
You could with css position 2 (or more) canvases over each other and let each work as a layer. Im not sure Exactly how to do this with css, but i've done something similar, have to canvases over eachother, one for 2d-content and one for webgl and the user could easily swap between them
<div height="640" style="position: absolute;">
<canvas width="640" style="position: absolute;visibility: hidden;" height="640" tabindex="1"></canvas>
<canvas width="640" height="640" style="visibility: hidden;position: absolute;"></canvas>
</div>
I guess that code is not bullet proff nor correct, but it works. Hope this helps.
If it doesnt I would use the workaround you mentioned. (I actually made a app like that where I drew 2d shadows to an offscreen canvas and drew it over the main canvas with transparency, looked pretty neat)
Upvotes: 1