为什么在 HTML5 Canvas 上重复绘制半透明填充不能完全覆盖它?

pit*_*zle 6 javascript html5-canvas

这到底是怎么回事?

为什么混合突然停止于255,214,214,255?这是预期的行为吗?

我以为它最终会击中255,255,255,255,但事实并非如此。它甚至还没有接近。红色矩形从一开始就不会消失为白色,它255,214,214,255永远保持彩色。

const ctx = document.querySelector('canvas').getContext('2d');

// draw "red"
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 300, 200);

function loop() {
    
    // log new colors
    if (getCurrentColor() !== loop.lastColor) {
        console.log(loop.lastColor = getCurrentColor());
    }
    
    // draw "transparent white" repeatedly
    ctx.fillStyle = 'rgba(255,255,255,0.01)';
    ctx.fillRect(0, 0, 300, 200);
    
    // schedule next iteration
    requestAnimationFrame(loop);
}
loop(); // start loop

function getCurrentColor() {
    return ctx.getImageData(0, 0, 1, 1).data.join(',');
}
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
    <head></head>
    <body>
        <canvas width="300" height="200"></canvas>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

解释和解决方案都受到高度赞赏!:P

pit*_*zle 2

HTML/JS Canvas 的底层图形缓冲区是Bitmap,它只允许从到 的Integer颜色值。这意味着每个渲染操作的输出都必须四舍五入0255

假设您从颜色值开始214。如果你然后混合214 * 0.99 + 255 * 0.01,理论上你会得到214.41。但这随后会四舍五入214以存储在画布位图中!
所以,本质上,你被困在214(或任何其他值,只要你的步骤小于0.5)xD

不幸的是,没有办法用纯 JavaScript 来规避这个问题,因为您无法更改图形缓冲区架构或混合/合成操作。
但我相信如果你真的想的话,你可以破解它。通过、 或类似的东西实现Float32图形缓冲区。WebGL API