【问题标题】:Using globalCompositeOperation in few phases分几个阶段使用 globalCompositeOperation
【发布时间】: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 ???

如果可能的话,如何告诉上下文从某个点开始合成?

我可以创建另一个画布并在那里绘制蒙版……然后在主画布上绘制新的画布。但是有更好的解决方案吗?

【问题讨论】:

    标签: html canvas clipping


    【解决方案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; }
    #canvas{border:1px solid red;}
    <canvas id="canvas" width=300 height=300></canvas>

    【讨论】:

    • 所以是 2 幅画布。只是以为我缺少globalCompositeOperation
    • 您的直觉是正确的 :-) 通常的做法是创建一个临时画布来处理子元素。祝你的项目好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    • 2020-07-27
    • 2013-04-27
    相关资源
    最近更新 更多