分几个阶段使用 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的主要内容,如果未能解决你的问题,请参考以下文章

程序设计分为几个步骤?

如何启用 Google 两阶段验证密码 与 问题解决

剑桥英语都包括啥?分别分几级?

剑桥英语等级证书分几个等级,如何划分?

洛谷 P1273 有线电视网(dp)

python学科课程分几个部分?