纯canvas实现轻量粒子背景需控制粒子数≤200,避免全量clearrect,用透明度叠加模拟残影;初始化批量生成粒子,每帧仅更新位置与绘制;鼠标交互用距离平方判断,连线颜色/半径随距离衰减,关键计算须移出渲染循环。

用 canvas 实现轻量粒子背景,别碰第三方库
纯 canvas + 原生 JS 就能跑出流畅粒子背景,不需要 three.js 或 particles.js。关键在控制粒子数量(建议 ≤ 200)、避免每帧重绘整个画布、跳过离屏粒子的计算。
常见错误是直接用 requestAnimationFrame + 全量 clearRect,结果 60fps 下 CPU 占用飙升。正确做法是只擦除局部区域,或干脆不擦——靠粒子自身渐隐+重绘覆盖来模拟运动残影。
- 初始化时用
ctx.fillStyle = 'rgba(255,255,255,0.1)'填充全画布一次,之后每帧只绘制新粒子,靠透明度叠加实现拖尾 - 粒子位置更新用欧拉积分:
particle.x += particle.vx; particle.y += particle.vy;,别用物理引擎式复杂公式 - 鼠标交互只需监听
mousemove,记录clientX/clientY,在距离50px内增大粒子速度并改变方向,无需 DOM 事件委托
requestAnimationFrame 里别做耗时计算
粒子动画卡顿,90% 是因为把坐标生成、距离判断、颜色插值全塞进渲染循环。这些该提前算好或缓存。
比如粒子初始位置,别在每帧用 Math.random() 生成;而是在初始化时批量生成并存入数组。又比如鼠标距离判断,用 (dx*dx + dy*dy) (即 <code>50*50)代替 Math.sqrt,省掉开方运算。
- 粒子颜色若需渐变,预生成 256 个
rgba(r,g,b,a)字符串数组,用整数索引查表,别现场拼接 - 所有
Math.sin/Math.cos若用于周期性运动(如绕中心浮动),用查表法或简化为y = Math.sin(t * 0.01) * 20这类线性缩放,避免高频三角函数调用 - 避免在动画循环中调用
getBoundingClientRect(),Canvas 尺寸变化时单独处理 resize 逻辑,存canvas.width/canvas.height到闭包变量里复用
响应式 canvas 粒子背景必须重置缓冲区
直接写 canvas.style.width = '100%'; canvas.style.height = '100%' 会导致图像拉伸模糊,且粒子坐标错乱。Canvas 的 width 和 height 属性才是实际绘图缓冲区尺寸,CSS 只控制显示大小。
正确做法是监听 window.resize,然后同步设置:canvas.width = canvas.offsetWidth; canvas.height = canvas.offsetHeight;,再重新初始化粒子位置(否则旧坐标会超出新画布边界)。
- resize 后别直接清空重绘,先保存当前粒子状态(如速度向量),再按新尺寸等比缩放位置,保持动效连贯
- 移动端要注意
window.devicePixelRatio,高 DPI 屏幕下应设canvas.width = canvas.offsetWidth * window.devicePixelRatio,否则粒子边缘发虚 - 避免频繁触发 resize,用
setTimeout防抖,延迟 100ms 再执行重置,防止滚动时反复重绘
粒子连接线性能陷阱:别用 lineTo 逐条画
想让粒子间连线形成网状效果?用 beginPath + moveTo + lineTo 循环画线,100 个粒子就会产生近 5000 次路径操作,严重拖慢帧率。
更优解是把连接关系建模为稀疏邻接表:每个粒子只记录距离最近的 3–5 个邻居索引,而非暴力两两比较。再用单次 strokeStyle + 批量 lineTo 绘制,或干脆改用 putImageData 直接操作像素(适合静态连接图)。
- 距离判断加阈值过滤:
if (dist > 120) continue,跳过远距离无效连接 - 连接线颜色随距离衰减:
ctx.strokeStyle = `rgba(255,255,255,${0.5 - dist/250})`,注意 alpha 最小值设为 0.05,避免完全透明导致渲染器仍执行绘制 - 如果只要视觉“连线感”,可用粒子自身大小随距离缩小模拟(
radius = Math.max(0.5, 2 - dist/60)),省去所有连线逻辑
粒子动画真正难的不是“怎么动起来”,而是“怎么动得省、动得稳、动得不抢主线程”。很多效果崩坏,是因为在 requestAnimationFrame 里悄悄塞进了 DOM 查询、字符串拼接、未截断的递归或没节流的事件监听——这些和粒子本身无关,却决定你最后看到的是丝绸还是卡顿马赛克。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











