我一直在用 HTML 和 JS 开发一个多人绘图应用程序,但我遇到了一个奇怪的问题。
绘制时,根据需要多次将画笔图像(从 .png 加载)绘制到 Canvas (使用 drawImage
)以在鼠标移动的位置形成一条连续的线。在我添加不透明度支持之前,这一切都很好。现在我可以看到,当我将不透明度调低时,即使我来回涂鸦很长时间, Canvas 上的图像也永远不会达到我试图绘制的全色。这导致了一种奇怪的情况,当我可以绘制一条实心的、完全不透明的黑线,然后将不透明度设置得非常低,并尝试用透明的红色在黑线上逐渐着色,但黑色永远不会完全褪色为红色。
我不明白这是怎么回事。我做了 a fiddle这说明了这个问题。在 fiddle 中,无论矩形在前一个矩形的顶部绘制多少次,它永远不会达到纯黑色。
HTML:
<canvas id="myCanvas" width="300" height="150"></canvas>
Javascript:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
for(var i=0;i<10000;i++) {
ctx.save();
ctx.globalAlpha=0.01;
ctx.fillStyle='black';
ctx.fillRect(40, 40, 130, 80);
ctx.restore();
}
这对我来说毫无意义。有谁知道为什么会发生这种情况,我该如何解决?
最佳答案
当您使用不透明度为 A% 的颜色进行绘制时,结果将是现有颜色与您正在绘制的(不透明)颜色之间的 A%。
在这种情况下,您将在纯黑色上绘制 1% 不透明的红色。结果将是从黑色到红色的 1%。称之为“红黑色”。
再做一次,结果将是“红黑”和红色之间的 1%,也就是 1.99% 的红色。接下来是 ~2.97% 红色,然后是 ~3.94% 红色,依此类推。请注意,您并不是每次都添加 1%,而是从前一笔画离开您的地方前进 1% 到终点。
从数学上讲,您将无限接近全红,但永远不会真正达到它。
但是图形还有一个额外的因素:只有 256 个离散值表示您可以拥有多少红色:0 表示没有,最多 255 表示完整。一开始,您的 1% 将添加 2-3 个“单位”的红色(取决于四舍五入)。这将持续一段时间,并逐渐下降到一次只添加 1 个“单位”。最后,您达到 207。此时,还剩 48 个“单位”变为全红色,其中 1% 为 0.48 个“单位”。这还不够,由于四舍五入,您将再次得到 207。这就是为什么在一定次数的笔划后您不再看到任何效果。
举一个更明显的例子,假设您使用 50% 的不透明红色进行绘制。第一击将使您到达那里的 1/2 路。第二个给出了另一半,所以 1/2 + 1/4 = 3/4。然后是 7/8,然后是 15/16... 再一次,您永远也达不到它。尽管有趣的是,在这种情况下,255 单位的东西可以帮助您解决问题,因为您总是会添加至少 0.5 个“单位”,这将向上舍入为 +1,直到您达到全红。
关于javascript - HTML Canvas 透明度永远不会达到不透明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42904090/