我无法看到这已经发布了,所以就这样了。
让我说我在画布上画了2个方格。
LinkedHashMap
生成此图像:
如果我将globalAlpha更改为0.5,我会得到:
但是,我希望产生这个:
同样,所有像素都是透明的,其下面的任何图像都会出现,但红色三角形创建的像素将覆盖绘制它的现有蓝色三角形。
并且ctx.globalComposisteOperation在这种情况下似乎没有帮助,因为它还考虑了透明度以及我希望保留两个方块的事实。
有没有办法用现有方法做到这一点?
答案 0 :(得分:1)
使用合成在绘制之前清除红色三角形。
使用合成比剪辑略好,因为您不必清除剪辑。清除剪辑需要保存整个上下文状态,然后恢复该上下文状态 - 涉及许多属性。合成只需要前后改变1个属性。
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// fill the blue rect
ctx.fillStyle = "rgba(0,0,255,0.5)";
ctx.beginPath();
ctx.moveTo(25, 0);
ctx.lineTo(50, 50);
ctx.lineTo(0, 50);
ctx.lineTo(25, 0);
ctx.fill();
// define the red rect path
ctx.beginPath();
ctx.moveTo(50, 0);
ctx.lineTo(75, 50);
ctx.lineTo(25, 50);
ctx.lineTo(50, 0);
// clear the red rect path using compositing
ctx.globalCompositeOperation='destination-out';
ctx.fillStyle='black';
ctx.fill();
ctx.globalCompositeOperation='source-over';
// fill the red rect
ctx.fillStyle = "rgba(255,0,0,0.5)";
ctx.fill();

body{ background-color:white; }
#canvas{border:1px solid red; }

<canvas id="canvas" width=512 height=512></canvas>
&#13;
答案 1 :(得分:1)
以photoshop的方式进行,并创建图层来为您完成工作。创建图层(第二个画布)并不比加载图像更麻烦。您可以创建数十个并且没有任何问题,这使得这种工作变得简单。
首先创建第二个画布(图层)
// canvas is original canvas
var layer = document.createElement("canvas");
layer.width = canvas.width; // same size as original
layer.height = canvas.height;
var ctx1 = layer.getContext("2d");
然后使用alpha = 1;
在第二个画布上绘制三角形var tri = (x,c)=>{
ctx1.fillStyle = c;
ctx1.beginPath();
ctx1.moveTo(25 + x, 0);
ctx1.lineTo(50 + x, 50);
ctx1.lineTo(0 + x, 50);
ctx1.closePath();
ctx1.fill();
}
tri(0,"#00f");
tri(25,"#f00");
然后只需使用您想要的Alpha值在您正在处理的画布上绘制该图层。
ctx.globalAlpha = 0.5;
ctx.drawImage(layer,0,0);
如果您不需要额外的图层,请通过取消引用来删除画布和上下文。
ctx1 = undefined;
layer = undefined;
或者您可以保留图层,并为背景制作另一个图层并实时混合以使FX恰到好处
//
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
var ctx = canvas.getContext("2d");
var layer = document.createElement("canvas");
layer.width = canvas.width; // same size as original
layer.height = canvas.height;
var ctx1 = layer.getContext("2d");
var tri = (x,c)=>{
ctx1.fillStyle = c;
ctx1.beginPath();
ctx1.moveTo(25 + x, 0);
ctx1.lineTo(50 + x, 50);
ctx1.lineTo(0 + x, 50);
ctx1.fill();
}
tri(0,"#00f");
tri(25,"#0f0");
tri(50,"#f00");
ctx.globalAlpha = 0.5;
ctx.drawImage(layer,0,0);
layer = ctx1 = undefined;
答案 2 :(得分:0)
您可以在绘制之前清除第二个矩形的区域。
var c = document.getElementById('game'),
ctx = c.getContext('2d');
ctx.globalAlpha = 0.5;
ctx.fillStyle = "blue";
ctx.fillRect(0, 0, 50, 50);
// Clear the extra bit of the blue rectangle
ctx.clearRect(25, 25, 25, 25);
ctx.fillStyle = "red";
ctx.fillRect(25, 25, 50, 50);
&#13;
<canvas id="game" width="320" height="240"></canvas>
&#13;
答案 3 :(得分:0)
我诚实地建议只改变颜色并避免使用alpha。
var c = document.getElementById('game'),
ctx = c.getContext('2d');
ctx.fillStyle = "#8080FF";
ctx.fillRect(0, 0, 50, 50);
ctx.fillStyle = "#ff8080";
ctx.fillRect(25, 25, 50, 50);
<canvas id="game" width="320" height="240"></canvas>
答案 4 :(得分:0)
saveMyClass(updatedMyClass: MyClass){
//saving MyClass using http service
//return the saved MyClass or error
var savedMyClass : MyClass = someLogicThatReturnsTheSavedObject(updatedMyClass);
if(isSomeCondition)
return Promise.reject(new Error('No reason but to reject'));
else
return new Promise<MyClass>(resolve => {setTimeout( ()=>resolve(savedMyClass),1500 )} );
}
只需使用clip()获取当前路径,使用clearRect清除其中的所有内容,然后正常绘制路径。
答案 5 :(得分:0)
@markE是对的,使用合成而不是剪辑(非常重)。
然而,只有你用rgba颜色绘制所有内容时,他的解决方案才有效。也许我错误地读了你的问题,但是如果你是从一个不透明的形状出发并希望它变得透明,那么你应该使用copy
gCO和globalAlpha
属性。
由于drawImage
比fill
快,因此性能影响较小,并且可以让您执行淡出效果;但这实际上取决于你的需求。
var ctx = c.getContext('2d');
// initial blue
ctx.fillStyle = "#0000FF";
ctx.beginPath();
ctx.moveTo(25, 0);
ctx.lineTo(50, 50);
ctx.lineTo(0, 50);
ctx.lineTo(25, 0);
ctx.fill();
setTimeout(function drawRed() {
ctx.fillStyle = "#FF0000";
ctx.beginPath();
ctx.moveTo(50, 0);
ctx.lineTo(75, 50);
ctx.lineTo(25, 50);
ctx.lineTo(50, 0);
ctx.fill();
}, 500);
btn.onclick = function makeItTransparent() {
// if we weere to make this into an animation, we would set it only once
ctx.globalCompositeOperation = 'copy';
ctx.globalAlpha = .8;
// draw the canvas on itself
ctx.drawImage(c, 0, 0);
// once again, in an animation we won't reset this to default
ctx.globalAlpha = 1;
ctx.globalCompositeOperation = 'source-over';
};
/* checkboard background */
canvas {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGElEQVQYlWNgYGBowIKxgqGgcJA5h3yFAOI3GQFqqi5ZAAAAAElFTkSuQmCC");
}
<canvas id="c"></canvas>
<button id="btn">make it transparent</button>