Combining two or more Canvas elements with some sort of blending
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 mor开发者_运维技巧e 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.).
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.
If You Want 'Normal' Blend Mode
- Ensure that your
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.
If You Need 'Normal' Blend Mode on a Single Canvas
- If you absolutely must flatten them to a single canvas (e.g. you want to create a data uri from the result) then use
drawImage
with one canvas as the source 'image'. For example, see:
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images#Using_other_canvas_elements
If You Want Simple Masking, Lighter, or Darker
- Use the
globalCompositeOperation
property of the canvas context and usedrawImage
with one canvas as the source. See an example here:
https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
If You want Photoshop-Style Blend Modes
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.
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)
I think you are looking for something like the pixastic library (Documentation).
精彩评论