HTML5 Canvas 粒子特效不能依赖 CSS 滤镜,需用 requestAnimationFrame 驱动 Canvas 2D API 手动更新绘制;粒子系统本质是数组管理对象,可用离屏 Canvas + shadowBlur + globalCompositeOperation 实现光晕效果,性能优化关键在于对象池复用。
直接说结论:filter CSS 属性(比如 blur()、hue-rotate())对 Canvas 内容无效,除非你把整个 当成普通 DOM 元素去滤镜——但这滤的是最终渲染图层,不是粒子本身。真正在 Canvas 上做粒子动效,得自己算位置、颜色、生命周期,用 requestAnimationFrame 驱动,再用 ctx.drawImage() 或 ctx.fillRect() / ctx.beginPath() 一帧一帧画出来。
粒子系统本质是数组管理:每个粒子是对象,含 x、y、vx、vy、life、size、color 等字段。主循环里更新+绘制,不依赖任何“滤镜”API。
life--),移除 life 的粒子
ctx.globalAlpha 控制透明度,比反复改每个粒子 color 更快ctx.fillRect(x, y, size, size)(矩形)或 ctx.arc(x, y, radius, 0, Math.PI * 2)(圆形),避免频繁调用 beginPath/stroke
Uint8ClampedArray 直接操作 ctx.getImageData().data,但开发成本高、调试难Canvas 本身不提供“粒子发光模糊”,但可以用两层 Canvas 模拟:主层画粒子,副层(离屏)画带半透明的放大版粒子,再用 globalCompositeOperation = 'lighter' 叠加出光晕感。
canvas(document.createElement('canvas')),尺寸建议是屏幕的 1.5 倍,避免边缘裁剪ctx.clearRect(0,0,w,h),别用 fillRect 填黑——那会吃掉光晕叠加效果ctx.shadowBlur = 12 + ctx.shadowColor = 'rgba(255,100,100,0.6)' 能快速伪造柔边光斑mainCtx.drawImage(offscreencanvas, 0, 0) 合并,比逐个粒子加 shadow 性能好得多如果粒子要带旋转、透视、贴图、物理碰撞,或者数量上万,Canvas 2D 会卡顿。这时才该切到 WebGL:THREE.Points + THREE.PointsMaterial 是最轻量的入口。
PointsMaterial.sizeAttenuation = true 让粒子随距离自动缩放,模拟景深vertexShader 控制粒子运动逻辑,比 CPU 更新数组快一个数量级
THREE.Sprite 渲染的是带 alpha 的图片,而 Points 默认是纯色点——要发光效果还得配自定义 shader 或叠加 bloom 后处理(需 EffectComposer)真正容易被忽略的点:粒子系统的性能瓶颈往往不在绘制,而在数组 push/splice 和对象创建。用对象池复用粒子实例,比每帧 new Particle() 省 30% 以上 GC 压力。