How do a cut out one shape from another (XOR) in Canvas when shape is partially transparent?

|▌冷眼眸甩不掉的悲伤 提交于 2021-02-08 05:20:52

问题


Normally to cut one shape out from another using Canvas, I've used the globalCompositeOperation option "xor":

var c2 = document.getElementById('canvas').getContext('2d');
c2.globalCompositeOperation = "xor";
c2.fillRect(0, 0, 200, 200);
c2.fillRect(170, 0, 30, 30); // shape 2 is cut out from shape 1

However, when either the fillStyle has a alpha value < 1, or the globalAlpha of the context is < 1, the "cut-out" shape is no longer completely invisible.

Specifically, if the alpha is >0.5 and <1, you see a lighter version of the shape. If the alpha is 0.5, there is no cut-out visible at all. And if alpha is <0.5, we get the inverse: the shape that's supposed to be cut out is in fact darker than the first shape.

This can be seen at http://jsfiddle.net/N7aXY/2/.

You can try changing the alpha value to see the different effects.

Is there any way to completely cut out a shape when the background shape has an alpha < 1?


回答1:


Ok, this is a bit "hackish", but here we go anyway:

  1. Set compositing to XOR.
  2. Draw to "cut" shape2 from shape1 normally.
  3. Save the canvas.
  4. Set compositing to normal (source-over).
  5. Set globalAlpha to your desired level.
  6. Clear the canvas and redraw the saved image.
  7. Results: globalAlpha and globalCompositing work in harmony!

Here is code and a Fiddle: http://jsfiddle.net/utttk/1/

ctx.fillStyle="red";
ctx.globalCompositeOperation="xor";
ctx.fillRect(0,0,200,200);
ctx.fillRect(170,0,30,30);
var png=canvas.toDataURL();
ctx.globalCompositeOperation="source-over"; // "normal" compositing
ctx.globalAlpha=.2;
var image=new Image();
image.onload=function(){
   ctx.clearRect(0,0,canvas.width,canvas.height);
   ctx.drawImage(image,0,0);
}
image.src=png;


来源:https://stackoverflow.com/questions/15579126/how-do-a-cut-out-one-shape-from-another-xor-in-canvas-when-shape-is-partially

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!