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

标签 javascript html canvas graphics colors

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/

相关文章:

javascript - 使多边形变小

Javascript:从另一个 html 页面获取单选按钮值

javascript - 三星智能电视 SDK - Web Socket

javascript - Canvas 内元素中的事件

html - 当 img 标签放在里面时,Aside 标签不会向左浮动

html - css @media 移动/桌面 : ensuring desktop doesn't show mobile css

css - 如何在其相应的容器中包含 sigmajs 图

javascript - 如何根据 AngularJS 输入 class=ng-invalid 设置 Twitter Bootstrap class=error?

javascript - 使用不同的参数进行成功回调

javascript - li slideDown 有效,但是当 slideUp 时它只是弹出而不滑动