Html HTML5 中填充笔划的透明度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9231531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 22:27:32  来源:igfitidea点击:

Transparency of a filled stroke in HTML5

htmlcanvasopacityfillstroke

提问by Mathieu

I'm working on a doodling app in HTML5 and I would like to do a sort of bucket feature. The idea is to draw a path and it will be closed and filled with the selected colour (colour of the stroke). It works quite well with solid colours, but if I want to have a transparent stroke and fill, I run into this problem: http://imgur.com/0N3MW

我正在开发一个 HTML5 涂鸦应用程序,我想做一种存储桶功能。这个想法是绘制一条路径,它将被关闭并填充选定的颜色(笔触的颜色)。它适用于纯色,但如果我想有一个透明的笔触和填充,我会遇到这个问题:http: //imgur.com/0N3MW

What happens is the fill is done until the middle of the stroke (the actual sampling point of the path) so there's a line of half the size of the stroke inside the shape which is darker because it's the intersection of the fill and the stroke.

发生的情况是填充完成直到笔画的中间(路径的实际采样点),因此形状内部有一条笔画大小一半的线,它更暗,因为它是填充和笔画的交点。

Do you see any workaround for this?

你看到任何解决方法吗?

Unfortunately, I can't post to JSFiddle right now because it's on READ ONLY mode. But you should be able to see what I'm talking about live in this sandbox: http://bit.ly/AbaMLl(The website and library is unrelated to what I'm using, it's just a canvas sanbox I found)

不幸的是,我现在无法发布到 JSFiddle,因为它处于只读模式。但是您应该能够在这个沙箱中实时看到我在说什么:http: //bit.ly/AbaMLl(该网站和库与我使用的内容无关,它只是我发现的一个画布沙箱)

Any ideas/leads welcome :)

欢迎任何想法/线索:)

采纳答案by Mathieu

Simon's answer was correct at the time but it now seems that Chrome 36 has corrected a bug which affects his solution and it no longer works. It already didn't work on Firefox and it seems to be the expected behaviour: https://bugzilla.mozilla.org/show_bug.cgi?id=898375

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

So, how do you get this done?
You first need another canvas.
Draw your filled and stroked shape on this canvas without opacity (not in the colour and no globalAlpha).
Now, draw set the globalAlpha to whatever you want on your main canvas.
Draw the first canvas on your main one.
Set the globalAlpha to whatever you had on your main canvas.
Done.

那么,你如何做到这一点呢?
您首先需要另一个画布。
在这个画布上绘制你的填充和描边形状,没有不透明度(不是颜色也没有 globalAlpha)。
现在,在主画布上绘制设置 globalAlpha 为您想要的任何内容。
在主要画布上绘制第一个画布。
将 globalAlpha 设置为您在主画布上的任何内容。
完毕。

回答by Simon Sarris

Sure, use ctx.globalCompositeOperation = 'destination-atop';and it ought to look the way you're expecting.

当然,使用ctx.globalCompositeOperation = 'destination-atop';它应该看起来像您期望的那样。

Like so: http://jsfiddle.net/UcyX4/

像这样:http: //jsfiddle.net/UcyX4/

(Take out that line in order to see the problem you're having)

(取出那条线以查看您遇到的问题)

Assuming its not the only thing drawn on canvas, you're probably going to have to draw this to a temporary canvas and then draw that canvas onto your normal one, otherwise it may ruin all the previously drawn shapes. So you'd need a system like so: http://jsfiddle.net/dATfj/

假设它不是画布上唯一绘制的东西,您可能必须将其绘制到临时画布上,然后将该画布绘制到普通画布上,否则可能会破坏之前绘制的所有形状。所以你需要一个像这样的系统:http: //jsfiddle.net/dATfj/

edit: code pasted in case of jsfiddle failure:

编辑:在 jsfiddle 失败的情况下粘贴的代码:

html:

html:

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

script:

脚本:

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);

回答by PhilMaGeo

2018 answer : use context.globalAlpha

2018 答案:使用 context.globalAlpha

ex : context.globalAlpha = 0.2;

前任 : context.globalAlpha = 0.2;