Javascript HtmlCanvas+;globalAlpha+;重叠=输出颜色不正确
我想画一堆几乎透明的白色矩形,它们彼此重叠 每个矩形的不透明度为0.01 我有100个重叠的矩形,我希望输出结果是所有不透明度的总和。换句话说,我希望结果是白色的,没有任何不透明度 但事实并非如此Javascript HtmlCanvas+;globalAlpha+;重叠=输出颜色不正确,javascript,canvas,opacity,alpha,overlapping,Javascript,Canvas,Opacity,Alpha,Overlapping,我想画一堆几乎透明的白色矩形,它们彼此重叠 每个矩形的不透明度为0.01 我有100个重叠的矩形,我希望输出结果是所有不透明度的总和。换句话说,我希望结果是白色的,没有任何不透明度 但事实并非如此 为什么? 如何得到我想要的结果 下面是一个简单的代码来说明这个问题 let canvas = document.createElement("canvas"); canvas.width = canvas.height = 512; let ctx = canvas.getCon
let canvas = document.createElement("canvas");
canvas.width = canvas.height = 512;
let ctx = canvas.getContext("2d");
ctx.fillStyle = "#000000";
ctx.fillRect(0,0,512,512);
ctx.fillStyle = "#ffffff";
ctx.globalAlpha = 0.01;
for(let i=0;i<100;i++){
let n = i*3;
ctx.fillRect(n,n,512-n,512-n);
}
document.body.appendChild(canvas);
let canvas=document.createElement(“canvas”);
canvas.width=canvas.height=512;
设ctx=canvas.getContext(“2d”);
ctx.fillStyle=“#000000”;
ctx.fillRect(0,0512512);
ctx.fillStyle=“#ffffff”;
ctx.globalAlpha=0.01;
对于(让i=0;i进行两种RGBA颜色的alpha混合(假设正常混合和合成模式),一般公式为
out = alpha * new + (1 - alpha) * old
但是,out
必须是一个整数(范围为0~255),因此我们必须在其上应用舍入(我猜舍入可能取决于实现以及它们存储颜色值的方式)
如果我们将alpha
取为0.1,并保持白色,则new
为255(白色为255,255,255),old为0(透明),
第一步,我们将
out = round( 0.1 * 255 + (1 - 0.1) * 0 );
// => 26
out = round( 0.1 * 255 + (1 - 0.1) * 26 );
// => 49
out = round( 0.1 * 255 + (1 - 0.1) * 49 );
// => 70
out = round( 0.1 * 255 + (1 - 0.1) * 70 );
// => 89
[...] // a few iterations later
// => 250
out = round( 0.1 * 255 + (1 - 0.1) * 250 );
// => 251
out = round( 0.1 * 255 + (1 - 0.1) * 251 );
// => 251
out = round( 0.1 * 255 + (1 - 0.1) * 251 );
// => 251
我们将有以下步骤
out = round( 0.1 * 255 + (1 - 0.1) * 0 );
// => 26
out = round( 0.1 * 255 + (1 - 0.1) * 26 );
// => 49
out = round( 0.1 * 255 + (1 - 0.1) * 49 );
// => 70
out = round( 0.1 * 255 + (1 - 0.1) * 70 );
// => 89
[...] // a few iterations later
// => 250
out = round( 0.1 * 255 + (1 - 0.1) * 250 );
// => 251
out = round( 0.1 * 255 + (1 - 0.1) * 251 );
// => 251
out = round( 0.1 * 255 + (1 - 0.1) * 251 );
// => 251
一旦达到该251、251、251
颜色值,无论要添加多少层,它都不会再改变颜色值,因此,如果该颜色的半透明版本的不透明度小于0.5,则无法通过分层该颜色的半透明版本来达到完全不透明的颜色
您的0.01
值将需要更多的迭代才能达到此稳定位置(153对38),但它将以较低的值(206)实现
请注意,颜色通常由其alpha预乘存储,这可能会在这些数字中增加一些舍入错误。感谢您的解释。昨天我几乎找到了一个没有任何逻辑的解决方案,只是通过实验(但我更愿意理解我在做什么,所以谢谢您)。我昨天找到的解决方案如下: