用canvas实现流星特效需模拟运动节奏、光迹衰减与随机质感,核心是数学控制+requestanimationframe驱动:全屏适配、对象池管理流星、渐变矩形或分段线绘制光迹、微抖动与碎裂增强真实感,并通过数量限制和节奏变化优化性能与沉浸感。

用 Canvas 制作流星划过夜空的背景特效,关键不在“画一条线”,而在于模拟真实流星的运动节奏、光迹衰减和随机质感。核心靠数学控制+帧动画驱动,不依赖物理引擎,轻量且可控。
全屏画布与流畅动画循环
先让 canvas 填满整个视口,并绑定窗口缩放响应:
- 设置
canvas.width = window.innerWidth、canvas.height = window.innerHeight - 监听
resize事件实时更新尺寸 - 用
requestAnimationFrame(animate)替代setInterval,保证每帧同步屏幕刷新率 - 每帧开头用
ctx.clearRect(0, 0, width, height)清空;若要拖尾感,可改用半透明黑色叠加(如ctx.fillStyle = 'rgba(0,0,0,0.05)'; ctx.fillRect(0,0,width,height))
流星对象的设计与运动逻辑
每颗流星是一个轻量对象,含位置、方向、速度、长度和生命周期,不追求精确物理,重在视觉节奏:
- 起点随机:x 在整行范围,y 在
-20 ~ 0(顶部之外),制造“从天而降”感 - 方向角控制在
-π/6 ~ π/6(约 -30°~30°),避免垂直下落,更自然 - 速度设为
2~8 px/帧,不同流星取不同值,形成快慢交错 - 每帧更新:
x += vx; y += vy;,当y > height + 50时回收或重置为新流星 - 用对象池管理流星数组(如固定 100 个对象反复使用),避免频繁内存分配
真实感光迹的绘制技巧
直接 lineTo 画细线太单薄。推荐两种高效方式:
-
带渐变的倾斜矩形:用
ctx.save()+ctx.translate(x,y)+ctx.rotate(angle),再画一个宽 1–3px、长 40–100px 的矩形,填充径向渐变(亮端 alpha=0.9,暗端 alpha=0.1) -
多段半透明线段:从起点开始,每 2–3 像素画一小段线,宽度和透明度逐段递减(如
ctx.lineWidth = 2.5 - i * 0.05,ctx.globalAlpha = 0.8 - i * 0.01) - 加微抖动:
x += Math.sin(Date.now() * 0.003 + id) * 0.4,让轨迹略带颤动 - 约 3%~5% 流星在中段触发“碎裂”:分裂成 2–3 条短轨迹,角度偏移 ±5°~10°,长度减半
性能与氛围优化要点
百颗流星同时运行容易卡顿,需主动平衡效果与开销:
- 星空背景提前画在离屏 canvas 上(仅小点状恒星),主循环只画流星,减少重复绘制
- 限制活跃流星数在 80~120 之间;低端设备自动降至 60 并关闭碎裂、简化渐变
- 流星长度控制在 30~120px,过长显著增加像素填充压力
- 真正提升沉浸感的是节奏:疏密有致(比如 2 秒内集中 3~4 颗,再空 3 秒)、偶尔出现一颗超亮长轨(alpha=1.0,长度 150px+)
- 可加全局亮度脉动:背景色轻微浮动,如
ctx.fillStyle = `hsl(220, 15%, ${50 + Math.sin(Date.now()*0.0005)*2}%)`
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











