将两个或多个画布元素以某种混合方式结合

40

是否可以将两个独立的canvas元素的内容合并到一个单独的canvas元素中?

就像在Photoshop中“合并”两个或多个图层一样,有没有类似的方法呢?

我能想到的是一个绕路的方法,但不是很确定。我将两个canvi(哈哈)的内容导出为.png格式的图像,然后让第三个canvas元素使用某种混合算法(异或、混合、负片等)绘制这两张图片。

4个回答

57
当然可以,而且您不需要使用任何有趣的库或其他东西,只需使用画布作为图像调用drawImage即可。 以下是一个示例,将两个画布元素合并到第三个画布上: ```js const canvas1 = document.getElementById('canvas1'); const canvas2 = document.getElementById('canvas2'); const canvas3 = document.getElementById('canvas3'); const ctx3 = canvas3.getContext('2d');
ctx3.drawImage(canvas1, 0, 0); ctx3.drawImage(canvas2, 0, 0); ```

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/

当然,您可以只使用两个(一个覆盖在另一个上面),但是三个效果更好。

如果您想要异或效果或其他效果,您可以随时更改 globalCompositeOperation


15

如果你想要“正常”的混合模式

  • 确保你的canvas元素在CSS中没有指定背景。这将使它们透明。
  • 绝对定位所有的canvas元素重叠在一起。例如,将它们全部包装在一个<div class="canvas-layers"> 中,然后使用类似以下的 CSS:

     /* 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 }
    
    让浏览器自动执行半透明区域之间的混合。

    如果您需要在单个画布上使用“正常”混合模式

    如果您想要简单的蒙版、更亮或更暗

    如果您想要类似于 Photoshop 的混合模式

    • 我创建了一个简单、轻量级、开源的库,可以在一个 HTML Canvas 上下文到另一个上执行 Photoshop 风格的混合模式:context-blender。以下是示例用法:

    • // Might be an 'offscreen' canvas
      var over  = someCanvas.getContext('2d');
      var under = anotherCanvas.getContext('2d');
      
      over.blendOnto( under, 'screen', {destX:30,destY:15} );
      

      请查看README了解更多信息。


1
你可以使用CSS将两个(或更多)画布叠放在一起,并让每个画布作为一个图层。我不确定如何使用CSS实现这一点,但我曾经做过类似的事情,将两个画布叠放在一起,一个用于2D内容,另一个用于WebGL,用户可以轻松地在它们之间切换。
<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>

我猜那段代码不是万无一失的,也不是完全正确的,但它能够工作。希望这会有所帮助。

如果不行的话,我会使用你提到的解决方法。(实际上我曾经制作过一个类似的应用程序,在一个屏幕外画出2D的阴影,并透明地将其覆盖在主画布上,看起来相当不错)


嘿,我已经让定位工作起来了http://www1.cybermed.org/workwork/E-Klinik%20related/HTML5%20Drawing/multiple_layer_drawing.html - 但是,我该如何合并两个或更多的图层呢...? - Abhishek
1
所以,我的理解是你最终想要一个包含所有信息的画布。如果是这样的话,我相信你可以将两个画布渲染成第三个画布作为图像,或者我可能误解了你的问题。但是,关于如何合并源和目标,你可以查看这个链接:http://www.nihilogic.dk/labs/canvas_sheet/HTML5_Canvas_Cheat_Sheet.png - Rickard

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接