javascript - HTML Canvas 透明度永远不会达到不透明

标签 javascript html5-canvas transparency

我一直在用 HTML 和 JS 开发一个多人绘图应用程序,但我遇到了一个奇怪的问题。

绘制时,根据需要多次将画笔图像(从 .png 加载)绘制到 Canvas (使用 drawImage)以在鼠标移动的位置形成一条连续的线。在我添加不透明度支持之前,这一切都很好。现在我可以看到,当我将不透明度调低时,即使我来回涂鸦很长时间, Canvas 上的图像也永远不会达到我试图绘制的全色。这导致了一种奇怪的情况,当我可以绘制一条实心的、完全不透明的黑线,然后将不透明度设置得非常低,并尝试用透明的红色在黑线上逐渐着色,但黑色永远不会完全褪色为红色。

colouring

我不明白这是怎么回事。我做了 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/

相关文章:

android - 如何禁用在 Android 的 webview 中选择整个 Canvas ?

ios - 如何知道用户是否在“设置”->“辅助功能”中禁用了透明度?

c# - 将具有透明度的 PDF 转换为无光栅化的 EPS

javascript - 单击透明图像

javascript - BabelPluginRelay : Expected plugin context to include "types", 但得到 :[object Object] when upgrading from 1. 1.0 到 1.4.1。为什么?

c# - 在 HTML 页面中加载资源的 JS 或任何其他语言 Hook

javascript - 更改 React Native 中其他组件的状态

php - XMLHttpRequest POST 到 PHP 删除加号

javascript - Canvas 响应式媒体屏幕最小宽度 - FabricJS

javascript - 如何从单个常见的 ajax 函数读取响应?