【发布时间】:2017-04-25 22:17:33
【问题描述】:
HTML5 画布上有数千个移动的粒子,我的目标是在每个粒子后面画一条短的淡入淡出的轨迹。一个很好且快速的方法是不完全清除每一帧的画布,而是用半透明的颜色覆盖它。这是一个只有一个粒子的示例:
var canvas = document.getElementById('display');
var ctx = canvas.getContext('2d');
var displayHeight = canvas.height;
var backgroundColor = '#000000';
var overlayOpacity = 0.05;
var testParticle = {
pos: 0,
size: 3
};
function render(ctx, particle) {
ctx.globalAlpha = overlayOpacity;
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 1.0;
ctx.fillStyle = '#FFF';
ctx.fillRect(particle.pos, displayHeight / 2, particle.size, particle.size);
}
function update(particle) {
particle.pos += 1;
}
// Fill with initial color
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
function mainLoop() {
update(testParticle);
render(ctx, testParticle);
requestAnimationFrame(mainLoop);
}
mainLoop();
<canvas id="display" width="320" height="240"></canvas>
有一个明显的问题:不透明度值低时,轨迹永远不会完全消失。在我的单粒子示例中,您可以看到(几乎)不褪色的水平线。我明白为什么会这样。 ColorA 被半透明的 ColorB 覆盖,基本上是线性插值,如果我们反复执行以下操作,ColorA 永远不会完全收敛到 ColorB:
ColorA = lerp(ColorA, ColorB, opacityOfB)
我的问题是,我该怎么做才能使它收敛到背景颜色,这样轨迹就不会永远保留在那里?使用 WebGL 或手动绘制轨迹不是有效的选项(分别是因为兼容性和性能原因)。一种可能性是遍历所有画布像素并手动将低亮度像素设置为背景颜色,尽管对于大型画布可能会变得昂贵。我想知道是否有更好的解决方案。
【问题讨论】:
标签: javascript html canvas graphics colors