将两个或多个 Canvas 元素与某种混合相结合

Posted

技术标签:

【中文标题】将两个或多个 Canvas 元素与某种混合相结合【英文标题】:Combining two or more Canvas elements with some sort of blending 【发布时间】:2011-10-10 21:38:13 【问题描述】:

是否可以将 2 个独立的画布元素的内容组合成一个画布元素?

类似于在 Photoshop 中“展平”两个或多个图层...?

我能想出一个办法,但不太确定。我以 .png 的形式导出两个 canvi (lol) 的内容,然后让第三个画布元素使用某种混合算法(xor、混合、否定等)绘制两个图像。

【问题讨论】:

【参考方案1】:

当然可以,而且你不需要任何有趣的库或任何东西,只需调用 drawImage 并将画布作为图像。

这是我将两个画布元素组合到第三个的示例:

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"   style="border: 1px solid black"></canvas>
<canvas id="canvas2"   style="border: 1px solid black"></canvas>
<canvas id="canvas3"   style="border: 1px solid black"></canvas>

http://jsfiddle.net/bnwpS/878/

当然你可以只用两个(一个放在另一个上),但三个是一个更好的例子。

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

【讨论】:

【参考方案2】:

如果您想要“普通”混合模式

确保您的canvas 元素没有在CSS 中指定背景。这将使它们保持透明。

绝对将所有canvas 元素置于彼此之上。例如,将它们全部包装在 &lt;div class="canvas-layers"&gt; 中,然后使用 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 

让浏览器自动将半透明区域相互叠加。

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

如果您绝对必须将它们展平为单个画布(例如,您想从结果中创建一个数据 uri),则使用 drawImage 并将一个画布作为源“图像”。例如:https://developer.mozilla.org/en-US/docs/Web/Guide/html/Canvas_tutorial/Using_images#Using_other_canvas_elements

如果您想要简单的遮罩,更亮或更暗

使用画布上下文的globalCompositeOperation 属性并使用drawImage 与一个画布作为源。在此处查看示例:https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html

如果您想要 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 了解更多信息。

【讨论】:

【参考方案3】:

您可以使用 css 位置 2(或更多)画布相互叠加,让每个画布作为一个图层工作。我不确定究竟如何用 css 做到这一点,但我做过类似的事情,必须互相画布,一个用于 2d 内容,一个用于 webgl,用户可以轻松地在它们之间切换

<div  style="position: absolute;">
    <canvas  style="position: absolute;visibility: hidden;"  tabindex="1"></canvas>
    <canvas   style="visibility: hidden;position: absolute;"></canvas>
</div>

我猜这个代码既不正确也不正确,但它确实有效。希望这可以帮助。

如果没有,我会使用您提到的解决方法。 (我实际上做了一个类似的应用程序,我在屏幕外画布上绘制了 2d 阴影,并以透明度将其绘制在主画布上,看起来非常整洁)

【讨论】:

嘿,我已经有定位工作www1.cybermed.org/workwork/E-Klinik%20related/HTML5%20Drawing/… - 但是,我如何组合两个或多个层......? 所以,我说得对吗,最后你想要一个包含所有信息的画布。如果是这种情况,我相信您可以将两幅画布渲染为第三幅图像,否则我可能会误解您的问题。但是对于如何结合源和目标,您可以查看nihilogic.dk/labs/canvas_sheet/HTML5_Canvas_Cheat_Sheet.png【参考方案4】:

我认为您正在寻找类似 @​​987654321@ 库 (Documentation) 的东西。

【讨论】:

以上是关于将两个或多个 Canvas 元素与某种混合相结合的主要内容,如果未能解决你的问题,请参考以下文章

将 SQL Server 图形数据库中的 MATCH 子句和 INNER JOIN 与混合模型相结合

将“for”循环与 if-else 语句相结合,每个“if”语句中都有多个条件

在 BigQuery 中将两个查询与 case 语句相结合

将列表与列表中不同长度的列表相结合

将 Python 脚本与不同的 GUI 相结合

OpenGL 与 OpenCV 相结合的计算机视觉教程 [关闭]