将两个或多个 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
元素置于彼此之上。例如,将它们全部包装在 <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
让浏览器自动将半透明区域相互叠加。
如果您需要在单个画布上使用“正常”混合模式
如果您绝对必须将它们展平为单个画布(例如,您想从结果中创建一个数据 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 与混合模型相结合