gpt4 book ai didi

javascript - 如何避免 html5 Canvas 上的永久粒子痕迹?

转载 作者:可可西里 更新时间:2023-11-01 13:24:29 26 4
gpt4 key购买 nike

HTML5 Canvas 上有成千上万个移动的粒子,我的目标是在每个粒子后面绘制一条短的渐变轨迹。一个很好且快速的方法是不完全清除每一帧的 Canvas ,而是用半透明颜色覆盖它。这是一个只有一个粒子的例子:

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 或手动绘制轨迹不是有效的选项(分别由于兼容性和性能原因)。一种可能性是遍历所有 Canvas 像素并手动将低亮度像素设置为背景色,尽管对于大 Canvas 来说这可能会变得昂贵。我想知道是否有更好的解决方案。

最佳答案

在某些情况下可行的解决方法是将 overlayOpacity 设置为 0.1(此值收敛),但仅每隔 x 次绘制一次,而不是在每次渲染调用中绘制一次。因此,当仅每隔一次绘制时,它或多或少保持相同的轨迹长度。

var renderCount = 0;
var overlayOpacity = 0.1;

function render(ctx, particle) {

if((renderCount++)%2 == 0) {
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);
}

显然缺点是它看起来更猛烈,也许这在您的情况下可能是 Not Acceptable 。

关于javascript - 如何避免 html5 Canvas 上的永久粒子痕迹?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41077303/

26 4 0