【发布时间】:2017-07-21 22:45:55
【问题描述】:
我一直在用 HTML 和 JS 开发一个多人绘图应用程序,但我遇到了一个奇怪的问题。
要进行绘制,画笔图像(从 .png 加载)根据需要多次绘制到画布上(使用 drawImage),以在鼠标移动的位置形成一条连续的线。在我添加不透明度支持之前,这一切都很好。现在我可以看到,当我将不透明度调低时,即使我来回涂鸦很长时间,画布上的图像也永远不会达到我试图绘制的全色。这导致了一种奇怪的情况,我可以绘制一条实心的、完全不透明的黑线,然后将不透明度设置得很低,并尝试用透明的红色逐渐在黑线上着色,但黑色永远不会完全褪色为红色。
我不明白这里发生了什么。我制作了 a 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();
}
这对我来说毫无意义。有谁知道为什么会发生这种情况,我该如何解决?
【问题讨论】:
-
因为数学。当您在纯黑色上绘制 1% 的不透明红色时,结果是 1% 的红色。再做一次,它是 1.99% 的红色。下一个是 2.97% 的红色。然后是 3.94% 红色等等。 100 个应用程序后,您的红色率为 63.4%。在 500 个应用程序之后,您将获得 99.33% 的红色。但是你永远不会达到 100% 红色,因为这就是数学与几何级数一起工作的方式......现在考虑到你只有 256 个离散值来表示有多少红色,你会因为四舍五入而失败。具体来说,当您达到 rgb(207,0,0) 时,您将无法应用足够的红色来达到 208,并且您会卡住。
-
@NiettheDarkAbsol 什么?这没有任何意义。好的,所以我正在以 1% 的不透明度绘制 255,0,0。这意味着它应该每次只添加 2.55(或者四舍五入为 3)红色。它应该在 100 次迭代中达到 255 红色......哦,等等,我不知道它是如何将 g 和 b 降低到 0......嗯,也许我假设错误。不管怎样,我见过的所有其他软件最终都会变成纯色。就像我仅在 HTML 中将两个图像叠加在一起,它们会按照我的预期进行。为什么画布不一样??
-
@NiettheDarkAbsol 好吧,我会被诅咒的。我刚刚在 PhotoShop 中尝试了同样的事情,并且惊讶地发现“问题”可以完全复制!即使有数百次笔划,低不透明度的红色画笔也永远不会完全去除黑线。嗯。那么酷,这不是问题。我现在要做的就是弄清楚如何使临时笔触图层看起来与真实图层不一样......
-
@NiettheDarkAbsol 如果您将评论转换为答案(自动,假设您可以这样做,或者复制粘贴)我会接受它,因为您是正确的。
标签: javascript html5-canvas transparency