·tech

Canvas 粒子系统实战 — 打造明日方舟风格背景

从零实现一个几何粒子系统:六边形/菱形粒子、连接线、鼠标交互、性能优化——全部用原生 Canvas API。

Canvas 粒子系统实战

本文记录 ARKNEXUS 粒子系统的实现过程。

设计目标

与常见的圆形粒子不同,方舟风格需要几何形状的粒子:

  • 六边形(主)
  • 菱形
  • 三角形
  • 短线段

基础架构

使用 requestAnimationFrame 驱动渲染循环:

typescript22 L
function animate(time: number) {
  const dt = (time - lastTime) / 16.667;
  lastTime = time;

  ctx.clearRect(0, 0, w, h);

  // 更新粒子位置
  for (const p of particles) {
    p.x += p.vx * dt;
    p.y += p.vy * dt;
    // 绘制...
  }

  // 绘制连接线
  for (let i = 0; i < particles.length; i++) {
    for (let j = i + 1; j < particles.length; j++) {
      // 距离判断 + 绘制连线
    }
  }

  requestAnimationFrame(animate);
}

鼠标交互

粒子对鼠标的排斥力实现:

typescript9 L
const dx = p.x - mouseX;
const dy = p.y - mouseY;
const dist = Math.sqrt(dx * dx + dy * dy);

if (dist < MOUSE_RADIUS) {
  const force = (1 - dist / MOUSE_RADIUS) * 1.5;
  p.vx += (dx / dist) * force * 0.05 * dt;
  p.vy += (dy / dist) * force * 0.05 * dt;
}

性能优化

  1. 距离平方比较:用 dx*dx + dy*dy < threshold² 替代 Math.sqrt
  2. 粒子数响应式:桌面 120、平板 60、手机 30
  3. DPR 限制:Retina 屏限制为 2x
  4. 离屏 Canvas:预渲染几何形状到离屏 canvas
  5. 可见性 API:页面隐藏时暂停循环

连接线算法

最朴素的是 O(n²) 遍历,在粒子数 < 150 时性能可接受。大规模场景可用空间哈希网格优化。

完整的实现代码见 [GitHub 仓库]。