纯CSS粒子仅支持静态或简单循环动画,因无逐帧计算能力,无法实现鼠标吸附、碰撞反弹等交互效果,且粒子数超150易致渲染瓶颈;canvas+requestAnimationFrame才是高密度、物理响应式粒子的正确方案。

纯CSS能做粒子背景,但仅限静态或简单循环动画;真交互、高密度、带物理响应的粒子必须用 canvas + requestAnimationFrame。
为什么纯CSS粒子只能“假装动”
CSS粒子本质是靠 box-shadow 或伪元素批量生成固定点位的“光斑”,再用 @keyframes 统一移动容器。它没有逐帧计算能力,无法实现:鼠标吸附、碰撞反弹、生命周期衰减、速度叠加。一旦粒子数超200,box-shadow 列表过长会触发浏览器渲染瓶颈,Chrome 下可能直接卡死或忽略部分阴影。
常见错误现象:box-shadow 坐标手动写几十行后发现漏逗号、animation-delay 没错开导致所有粒子同步闪、transform: translateY(-100vh) 在 Safari 里跳帧明显。
- 适用场景:星空滚动、网格渐隐、单色光点雨(无交互)
- 性能红线:建议控制在 150 个以内粒子,用 JS 动态生成
box-shadow字符串,别手敲 - 兼容性注意:
box-shadow多值在 IE 完全不支持,iOS Safari 对超长阴影列表解析不稳定
canvas 粒子系统怎么起步不翻车
从零搭一个可维护的粒子系统,核心就三步:初始化画布尺寸、定义粒子结构、用 requestAnimationFrame 替代 setInterval 驱动循环。别碰 setTimeout 控制粒子消散——它和渲染帧不同步,容易掉帧或堆叠。
关键参数差异:particle.radius 建议用 Math.random() * 1.5 + 0.5 而非固定值,避免视觉呆板;particle.opacity 衰减步长设为 0.008~0.012,太大会闪断,太小则消散拖沓。
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
- 画布尺寸必须监听
window.resize并重置canvas.width/canvas.height,只改 CSS 宽高会导致像素拉伸模糊 - 每次
requestAnimationFrame开头必调ctx.clearRect(0, 0, canvas.width, canvas.height),漏了就会糊成一片 - 删除粒子时用
for (let i = particles.length - 1; i >= 0; i--)倒序遍历,正序splice会跳过下一个元素
鼠标交互粒子怎么避免“粘滞感”
鼠标吸附不是简单把粒子 x/y 设为 mouse.x/mouse.y,那会丢失惯性,看起来像被磁铁吸住。真实做法是给粒子加一个朝向鼠标的加速度向量,再叠加原有速度。
示例逻辑:const dx = mouse.x - p.x; const dy = mouse.y - p.y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist 。这里 120 是感应半径,0.02 是加速度系数——调大变“猛拽”,调小变“轻推”。
- 别在每帧都算
Math.sqrt,先比dx * dx + dy * dy (120²),省 CPU - 鼠标移出区域后,粒子不能立刻失速,要保留原
vx/vy并加阻尼:p.vx *= 0.98; p.vy *= 0.98; - 移动端需绑定
touchmove并取touches[0],别只写mousemove
真正难的不是画出粒子,而是让几百个粒子在各种屏幕尺寸、设备性能下都保持 60fps —— 这取决于你删没删冗余计算、控没控粒子上限、有没有用 will-change: transform 提前告诉浏览器哪些层要动。这些细节不处理,再炫的算法也卡成幻灯片。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










