canvas粒子系统流畅运行的关键是结构清晰与职责分离:画布管理需动态适配视口和devicepixelratio,粒子更新与绘制必须分阶段执行,交互需用requestanimationframe节流,三者缺一即导致卡顿、模糊或错位。

Canvas粒子系统不是靠堆代码量实现的,而是靠结构清晰、职责分明的三块:画布管理、粒子数据、动画驱动。用错 requestAnimationFrame 或把更新和绘制混在一起,50个粒子就卡顿;不处理设备像素比(dpr),高清屏上粒子模糊或错位——这两点是绝大多数人上线前才发现的坑。
canvas.width/height 必须动态适配视口和 dpr
写死 canvas.width = 800 是最常见错误。Canvas 的 width 和 height 属性控制的是“绘图缓冲区”的逻辑像素数,不是 CSS 显示尺寸。如果只设 CSS 宽高,不重设 canvas.width/canvas.height,就会拉伸模糊。
- 每次 resize 时,先读取
window.devicePixelRatio,再设置:canvas.width = window.innerWidth * dpr,canvas.height = window.innerHeight * dpr - 同时用 CSS 把 canvas 缩放到视觉上的 100%:
canvas.style.width = '100vw'; canvas.style.height = '100vh'; - 最后别忘了告诉绘图上下文缩放:
ctx.scale(dpr, dpr),否则所有坐标和大小都得手动乘 dpr
粒子更新和绘制必须拆成两个阶段
把 particle.update() 和 particle.draw() 放在同一个循环里执行,等于每帧都做物理+渲染双重压力。浏览器一掉帧,粒子就“瞬移”或“拖影”。
用户要生成可打印的中文字帖/练习纸、导出多页 A4 PDF 报告,或把 SVG 设计稿零误差还原到 Canvas 时使用。本技能是「Canvas 内容工厂闭环」的总控,编排:网格渲染引擎(13 种教育网格+拼音标注) → 多页 PDF 导出(A4 合成) → SVG 精准复刻(坐标误差<0.001px)。触发词:生成字帖、练习纸、导出 PDF、SVG 转 Canvas、印刷级还原、A4 报告、米字格田字格。
- 维护两个独立数组:
particles(存所有粒子对象)和aliveParticles(只存当前存活的索引或引用),避免遍历时 splice - 更新阶段(
tick())只做纯数值运算:位置 += 速度、加阻尼、边界检测、生命周期减一 - 绘制阶段(
render())只调用ctx.beginPath()→ctx.arc()→ctx.fill(),不查 DOM、不 new 对象、不调 Math.random() - 如果粒子有透明度变化,用
ctx.globalAlpha控制,比反复设fillStyle更快
鼠标交互要用 requestAnimationFrame 节流,别直接绑 mousemove
原生 mousemove 在快速移动时每秒可触发上百次,但 requestAnimationFrame 最多 60 次。直接在 mousemove 里改粒子状态,会导致状态更新频率远超渲染频率,粒子“抽搐”或响应延迟明显。
- 只在
mousemove里更新一个全局mouse对象:mouse.x = e.clientX; mouse.y = e.clientY; - 在
tick()阶段统一计算粒子与鼠标的距离、施加力(如force = Math.max(0, 100 - dist) / 100) - 触摸设备要额外监听
touchmove,并加{ passive: false }防止默认行为拦截 - 如果要做“点击爆发”,在
mousedown里标记isExploding = true,然后在tick()中批量生成新粒子,而不是当场 push 到主数组
globalCompositeOperation = 'lighter' 是性能杀手,慎用
很多人想让粒子叠加发光,第一反应就是设 ctx.globalCompositeOperation = 'lighter'。这在 Safari 和旧版 Chrome 上会强制关闭硬件加速,CPU 合成导致严重卡顿,且背景稍有颜色就过曝发白。
- 仅在极少数需要强光融合的场景启用,用完立刻切回
'source-over' - 日常淡入淡出、余晖效果,用
fillStyle = 'rgba(255, 255, 255, 0.03)'多画几帧更稳 - 粒子数超过 300 且需混合效果时,优先考虑离屏 canvas:先在小 canvas 上画好粒子群,再用
drawImage贴到主 canvas,避免实时混合开销
真正难的不是让粒子动起来,而是让它们在不同屏幕、不同负载、不同交互节奏下都保持稳定帧率。更新和绘制分离、dpr 适配、交互节流——这三点漏掉任意一个,上线后用户看到的就不是酷炫动画,而是卡顿、模糊、错位的“PPT”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










