HTML5中填充轮廓的透明度

14

我正在开发一个基于HTML5的涂鸦应用程序,希望添加一个桶功能。思路是绘制路径,然后闭合并填充所选颜色(描边的颜色)。这在实心颜色下可以正常工作,但如果我想要使用透明的描边和填充,就会遇到以下问题:

问题是填充仅进行到描边的中心点(路径的实际采样点),因此形状内部有一条线,其长度等于描边大小的一半,并且因为它是填充和描边的交点而更加深色。

您可以在这个沙盒中实时查看我所说的内容。

3个回答

14
当然,使用 ctx.globalCompositeOperation = 'destination-atop'; , 应该可以呈现你期望的效果。就像这样: http://jsfiddle.net/UcyX4/ (如果要看到你遇到的问题,请删除这行代码)假设canvas上不只有这个图形,那么你可能需要将其绘制到一个临时画布上,然后再将该画布绘制到正常画布上,否则可能会破坏之前绘制的所有形状。所以你需要一个像这样的系统: http://jsfiddle.net/dATfj/。编辑:JSFiddle出错时可查看以下代码:

HTML:

<canvas id="canvas1" width="500" height="500"></canvas>

脚本:

var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');

var can2 = document.createElement('canvas');
can2.width = can.width;
can2.height = can.height;
ctx2 = can2.getContext('2d');

ctx.strokeStyle = 'rgba(0,0,0,0.7)';
ctx.fillStyle = 'rgba(0,0,0,0.7)';
ctx.lineWidth = 10;


// Stuff drawn normally before
// Here I draw one rect in the old way just to show the old way
// and show something on the canvas before:
ctx.beginPath();
ctx.rect(50,50,100,100);
ctx.fill();
ctx.stroke();


// Draw on can2 then draw can2 to can
ctx2.strokeStyle = 'rgba(0,0,0,0.7)';
ctx2.fillStyle = 'rgba(0,0,0,0.7)';
ctx2.lineWidth = 10;
ctx2.beginPath();
ctx2.rect(50,250,100,100);
ctx2.globalCompositeOperation = 'destination-atop';
ctx2.fill();
ctx2.stroke();

ctx.drawImage(can2, 0, 0);

很不幸,JSFiddle 给了我一个 404 错误,但是我尝试更改复合模式,它似乎可以工作。但你也是对的,我需要将我用于绘制形状的“中间”画布绘制到最终画布上,与最终形状一起。在 JSFiddle 恢复之际,我会尝试找出如何做到这一点 :) 再次感谢! - Mathieu
我把来自fiddle的所有代码都添加了进去,以防万一。祝你的项目好运! - Simon Sarris
这个已经不再起作用了(在Firefox上已经无法使用)。我正在寻找替代方案。更多信息请参见:https://bugzilla.mozilla.org/show_bug.cgi?id=898375 - Mathieu

6

2018年的答案是:使用context.globalAlpha

例如:context.globalAlpha = 0.2;


5

Simon的答案在当时是正确的,但现在看来,Chrome 36已经纠正了一个影响他的解决方案的错误,它不再起作用。 它在Firefox上已经不起作用,这似乎是期望的行为:https://bugzilla.mozilla.org/show_bug.cgi?id=898375

那么,你该如何完成它?
首先,您需要另一个画布。
在此画布上绘制填充和描边形状,而没有不透明度(不是颜色和没有globalAlpha)。
现在,在主画布上将globalAlpha设置为所需值。
在主画布上绘制第一个画布。
将globalAlpha设置为您在主画布上拥有的任何内容。
完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接