限时福利领取


节日特效效果图

一、背景痛点:为什么你的节日特效会卡顿?

春节特效开发最常遇到的三大问题:

  • 性能瓶颈:传统DOM操作在元素超过100个时明显卡顿
  • 兼容性问题:不同设备浏览器对CSS3特性的支持差异大
  • 移动端崩溃:低端机型内存不足导致页面闪退

以常见的红包雨效果为例,使用jQuery实现的版本在安卓千元机上平均FPS仅12-15帧,而优化后的方案可以达到55+帧。

二、技术选型:三套方案的实战对比

技术对比图

  1. CSS3动画
  2. 优点:开发简单、硬件加速
  3. 缺点:粒子数量 >200时性能骤降
  4. 适用场景:简单动效、UI装饰元素

  5. Canvas 2D

  6. 优点:可控性强、中等性能
  7. 缺点:需要手动管理绘制逻辑
  8. 适用场景:烟花/雪花等粒子效果

  9. WebGL

  10. 优点:极致性能(万级粒子)
  11. 缺点:学习曲线陡峭
  12. 适用场景:3D特效/复杂场景

实测数据对比(Redmi Note 10 Pro):

| 技术方案 | 100粒子FPS | 500粒子FPS | GPU内存占用 | |----------|------------|------------|-------------| | CSS3 | 58 | 22 | 120MB | | Canvas | 60 | 48 | 85MB | | WebGL | 60 | 60 | 65MB |

三、Canvas烟花效果完整实现

class Firework {
  /**
   * 烟花粒子构造函数
   * @param {number} x - 初始X坐标
   * @param {number} y - 初始Y坐标
   * @param {string} color - 粒子颜色
   */
  constructor(x, y, color) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.radius = Math.random() * 2 + 1;
    this.velocity = {
      x: (Math.random() - 0.5) * 8,
      y: (Math.random() - 0.5) * 8
    };
    this.alpha = 1;
    this.decay = Math.random() * 0.015 + 0.01;
  }

  update() {
    this.velocity.y += 0.05; // 模拟重力
    this.x += this.velocity.x;
    this.y += this.velocity.y;
    this.alpha -= this.decay;
    return this.alpha > 0;
  }

  draw(ctx) {
    ctx.save();
    ctx.globalAlpha = this.alpha;
    ctx.fillStyle = this.color;
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.fill();
    ctx.restore();
  }
}

// 初始化画布
const canvas = document.getElementById('fireworks');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

// 烟花粒子池
let particles = [];

function animate() {
  requestAnimationFrame(animate);

  // 清屏时保留淡出效果
  ctx.fillStyle = 'rgba(10, 10, 20, 0.2)';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  // 更新并绘制所有粒子
  particles = particles.filter(particle => {
    particle.draw(ctx);
    return particle.update();
  });
}

四、避坑指南

移动端适配三要素

  1. DPI适配:

    const dpr = window.devicePixelRatio || 1;
    canvas.style.width = `${canvas.width / dpr}px`;
    canvas.style.height = `${canvas.height / dpr}px`;
  2. 内存优化:

  3. 粒子数量控制在300以内
  4. 使用对象池复用粒子对象

  5. 触控事件:

    canvas.addEventListener('touchstart', (e) => {
      createFirework(e.touches[0].clientX, e.touches[0].clientY);
    }, { passive: true });

防内存泄漏技巧

  • 使用performance.memory监控内存
  • 页面隐藏时停止动画:
    document.addEventListener('visibilitychange', () => {
      if (document.hidden) cancelAnimationFrame(animationId);
    });

五、进阶:3D灯笼效果架构

  1. 使用Three.js创建基础场景
  2. 灯笼主体:红色圆柱体+黄色装饰线
  3. 光源处理:点光源模拟烛光效果
  4. 物理引擎添加悬挂摆动效果

动手实践

任务:修改上述烟花代码,实现以下效果: 1. 粒子初始速度与爆炸中心距离成正比 2. 添加空气阻力系数(建议值0.98) 3. 实现二次爆炸效果(当y速度反向时)

提示代码:

this.velocity.x *= 0.98;
this.velocity.y *= 0.98;

完整项目示例可访问GitHub仓库(文末评论区获取链接)。在实际开发中,建议先用Chrome的Performance面板分析每帧耗时,重点优化render和update阶段的性能瓶颈。

Logo

音视频技术社区,一个全球开发者共同探讨、分享、学习音视频技术的平台,加入我们,与全球开发者一起创造更加优秀的音视频产品!

更多推荐