用Canvas实现动态流星雨背景需模拟轨迹、亮度衰减与随机性:先设全屏canvas并用requestAnimationFrame驱动动画;每颗流星为带位置、速度、生命周期的对象,以渐变矩形或分段线绘制光迹,叠加抖动与碎裂效果;通过对象池复用、数量限制和离屏背景优化性能,注重疏密快慢节奏提升沉浸感。

用 Canvas 实现动态流星雨背景,核心是模拟流星的轨迹、亮度衰减、随机性与循环复用。不需要复杂物理引擎,靠数学公式和帧动画就能做出逼真效果。
一、基础Canvas设置与动画循环
先获取 canvas 上下文,设置全屏尺寸,并用 requestAnimationFrame 驱动持续重绘:
- 将 canvas 宽高设为窗口尺寸(
canvas.width = window.innerWidth),并监听resize事件同步更新 - 每帧先用
ctx.clearRect(0, 0, width, height)清空画布(或用半透明黑色叠加实现拖尾效果) - 避免 setInterval,坚持用
requestAnimationFrame(animate)保证流畅性和节电优化
二、流星对象建模与运动逻辑
每颗流星是一个含位置、速度、长度、透明度、生命周期的对象。关键不是“画线”,而是“画带渐变的倾斜矩形”来模拟光迹:
- 起点
(x, y)随机在顶部区域(如y = -20 ~ 0),x在整行范围内随机 - 方向角随机(如
-π/6 ~ π/6偏斜向下),速度v在 2~8 像素/帧之间浮动 - 用
Math.cos(angle) * v和Math.sin(angle) * v分解出vx、vy - 每帧更新位置:
x += vx; y += vy;,当y > height + 50时重置为新流星
三、真实感绘制:光迹+衰减+随机细节
直接用 lineTo 画细线太单薄。推荐用 带径向渐变的旋转矩形 或 多段叠加的半透明线段:
立即学习“前端免费学习笔记(深入)”;
- 对每颗流星,从起点开始,沿轨迹每隔 1~3 像素画一小段
ctx.fillRect,宽度递减、透明度递减(如 alpha 从 0.8 → 0.1) - 或更高效:用
ctx.beginPath()+ 多个ctx.lineTo()构成折线,再用ctx.strokeStyle = `hsla(${hue}, 80%, 70%, ${alpha})`设置渐变色透明度 - 添加微小抖动(
+ Math.sin(Date.now() * 0.002 + id) * 0.5)让轨迹不僵硬 - 约 5% 的流星加“碎裂”效果:到达中段时分裂成 2–3 条短轨迹,带轻微角度偏移
四、性能与视觉平衡技巧
百颗流星同时运行很容易卡顿,需主动控制数量与开销:
- 限制活跃流星总数(如 80~120),用数组池复用对象,避免频繁 new/delete
- 把星空背景(小点状恒星)预先画在另一离屏 canvas 上,主循环只画流星,减少重复绘制
- 流星长度控制在 30~120px,过长显著增加计算和像素填充压力
- 在低性能设备上自动降级:减少数量、关闭碎裂、简化渐变(改用纯色+固定 alpha)
不复杂但容易忽略——真正打动人的不是数量,而是节奏感:让流星有疏有密、有快有慢、偶尔划过亮光,配合轻微的全局亮度脉动(如背景色周期性微调),就很有沉浸感。



















