分几个阶段使用 globalCompositeOperation
Posted
技术标签:
【中文标题】分几个阶段使用 globalCompositeOperation【英文标题】:Using globalCompositeOperation in few phases 【发布时间】:2014-12-19 09:24:26 【问题描述】:我在我的上下文中画了很多东西。形状、文本、图像..
我想在globalCompositeOperation
的上下文中使用clip
方法来达到相同的效果(使用clip
对我来说更难执行,我不知道文本是否可能)
用户可以绘制几个形状。然后开始一个掩码阶段。绘制更多的形状,文本..将绘制到蒙版中,然后下一次绘制将在蒙版阶段被剪辑。然后继续常规绘图...
例如
用户绘制此图
然后开始蒙版模式,画了这两条红线
然后他停止在蒙版中绘制,并开始绘制矩形以考虑蒙版
最后应用了蒙版剪辑,结果应该是这样的
如果没有早期的图纸,我已经设法用线条剪裁矩形。
// Starting the mask phase
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineTo(240, 140);
ctx.moveTo(80, 20);
ctx.lineTo(300, 140);
ctx.stroke();
ctx.globalCompositeOperation = 'source-out';
ctx.fillStyle = 'cyan';
ctx.fillRect(50, 70, 250, 20);
// Setting the composition back
ctx.globalCompositeOperation = 'source-over';
但是当我在代码的开头添加我的图纸时,构图也会考虑它。
ctx.fillStyle = 'brown';
ctx.beginPath();
ctx.arc(80, 80, 50, 50, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = 'yellow';
ctx.fillRect(80, 60, 150, 40);
ctx.fillStyle = 'black';
ctx.font = '40pt arial';
ctx.fillText('Hello', 130, 110);
// How to tell the context to start from here the compisition ???
如果可能的话,如何告诉上下文从某个点开始合成?
我可以创建另一个画布并在那里绘制蒙版……然后在主画布上绘制新的画布。但是有更好的解决方案吗?
【问题讨论】:
【参考方案1】:您可以通过更改.globalCompositeOperation
在绘图流程中的任何位置更改合成模式。但是,正如您所发现的,任何新的合成模式也会影响现有的画布内容。
您的直觉是正确的,即使用第二个“舞台画布”进行合成,不会破坏您现有的内容。
您可以使用内存中的画布进行合成并创建带有擦除线的矩形。然后你可以将这个内存画布绘制到你的主画布上。由于合成是在您的内存画布上完成的,因此您现有的 circle-hello 内容不会受到合成的不利影响。
这是示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// create an in-memory canvas to do compositing
var c=document.createElement('canvas');
var cctx=c.getContext('2d');
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/temp6a.png";
function start()
ctx.drawImage(img,0,0);
addCompositedRectangle();
ctx.drawImage(c,0,0);
function addCompositedRectangle()
// resize the in-memory canvas
// Note: this automatically clears any previous content
// and also resets any previous compositing modes
c.width=300; // largest width;
c.height=140; // largest height;
// Starting the mask phase
cctx.strokeStyle = 'red';
cctx.lineWidth = 5;
cctx.beginPath();
cctx.moveTo(20, 20);
cctx.lineTo(240, 140);
cctx.moveTo(80, 20);
cctx.lineTo(300, 140);
cctx.stroke();
cctx.globalCompositeOperation = 'source-out';
cctx.fillStyle = 'cyan';
cctx.fillRect(50, 70, 250, 20);
// Setting the composition back
cctx.globalCompositeOperation = 'source-over';
body background-color: ivory; padding:10px;
#canvasborder:1px solid red;
<canvas id="canvas" width=300 height=300></canvas>
【讨论】:
所以是 2 幅画布。只是以为我缺少globalCompositeOperation
您的直觉是正确的 :-) 通常的做法是创建一个临时画布来处理子元素。祝你的项目好运!以上是关于分几个阶段使用 globalCompositeOperation的主要内容,如果未能解决你的问题,请参考以下文章