🌌 我是如何使用 HTML Canvas 构建受 GROK 启发的星空与流星 ✨
发布: (2025年12月13日 GMT+8 16:35)
6 min read
原文: Dev.to
Source: Dev.to
使用 HTML Canvas 重新实现 GROK 星场与流星效果
如果你见过 GROK 风格的星场动画,你一定了解它的氛围:缓慢、电影感的旋转、细微的闪烁,以及偶尔划过太空的流星。本篇文章拆解了一个 纯 HTML + CSS + JavaScript 的实现方式,完整复刻该效果——不依赖任何库或框架,仅使用 Canvas API。
🌌 该效果包含的内容
- 全屏 HTML5
<canvas> - 数百颗在屏幕外轨道上旋转的星星
- 自然的闪烁 / 发光模拟
- 稀有且优雅的流星
- 响应式尺寸调整处理
全部通过requestAnimationFrame流畅运行。
📁 项目结构
index.html → Canvas 容器
style.css → 全屏黑色背景
script.js → 动画逻辑与自定义配置
无需构建步骤——直接在浏览器打开 index.html 即可。
🧱 HTML:最小化的 Canvas 设置
Canvas 填满整个视口,作为我们绘制所有内容的渲染表面。JavaScript 文件放在底部加载,以确保在访问 Canvas 前 DOM 已就绪。
🎨 CSS:全屏、无干扰
html, body {
margin: 0;
padding: 0;
background: black;
overflow: hidden;
width: 100%;
height: 100%;
}
#starfield {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
overflow: hidden防止出现滚动条。position: fixed让 Canvas 锁定在屏幕上。pointer-events: none使 UI 元素能够覆盖在其上方。
🧠 JavaScript:核心概念
Canvas 与 Context
const canvas = document.getElementById("starfield");
const ctx = canvas.getContext("2d");
所有绘制都通过 2D 渲染上下文手动完成。
⭐ 星星数据模型
每颗星星以对象形式存储:
{
angle: Number,
radius: Number,
speed: Number,
size: Number
}
星星使用 极坐标 定义:
angle→ 旋转位置radius→ 距离中心的距离
这样实现圆周运动非常简洁。
🌍 Canvas 尺寸自适应处理
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
initStars();
}
每当窗口尺寸变化时:
- 更新 Canvas 的宽高。
- 重新生成星星以适配新尺寸,保持画面清晰且响应式。
✨ 初始化星场
const numStars = 360;
星星的创建方式如下:
stars = Array.from({ length: numStars }, () => ({
angle: Math.random() * Math.PI * 2,
radius: Math.random() * Math.sqrt(canvas.width ** 2 + canvas.height ** 2),
speed: Math.random() * 0.0003 + 0.00015,
size: Math.random() * 1.2 + 0.5,
}));
- 随机角度让星星均匀分布。
- 较大的半径使星星在视口之外轨道运行。
- 极小的角速度营造缓慢、电影感的运动。
🔄 动画循环
function animate() {
requestAnimationFrame(animate);
// clear, update, draw, spawn shooting stars, etc.
}
requestAnimationFrame(animate);
每一帧执行:
- 清除 Canvas。
- 更新星星位置。
- 绘制星星。
- 可能生成流星。
- 更新流星状态。
🌟 绘制旋转星星
star.angle += star.speed;
const x = centerX + star.radius * Math.cos(star.angle);
const y = centerY + star.radius * Math.sin(star.angle);
经典的圆周运动公式。
闪烁 / 发光效果
const flicker = 0.4 + Math.abs(Math.sin(Date.now() * 0.0015 + i)) * 0.5;
亮度通过以下方式伪造:
- 振荡的透明度。
- 每颗星星略有相位偏移。
简洁、快速且效果显著。
☄️ 流星
流星的出现频率被刻意设为稀少:
if (shootingStars.length === 0 && Math.random() < 0.01) {
// create a new shooting star
}
一次只能出现一颗,保持瞬间的独特感。每颗流星拥有位置、速度和寿命属性。
🎯 流星尾迹
尾迹使用 线性渐变 实现:
const grad = ctx.createLinearGradient(
s.x,
s.y,
s.x - s.vx * 35,
s.y - s.vy * 35
);
透明度向尾部逐渐减弱,形成自然的光痕效果,无需粒子系统。
⚙️ 简单的自定义
所有调参都集中在 script.js 中。
密度
const numStars = 360;
闪烁强度
// base brightness
0.4
// flicker amplitude
0.5
流星出现频率
Math.random() < 0.01
流星速度
vx: 3 + Math.random() * 2,
vy: 1 + Math.random() * 1.5
💡 扩展思路
- 基于鼠标的视差效果。
- 色彩偏移的星星。
- 不同速度的深度层。
- 渐变的太空背景。
- 星云噪声叠加层。
🧪 为什么这种做法有效
- 零依赖 —— 纯 JavaScript 与 Canvas。
- 极致性能 —— 简单的数学运算 + Canvas 渲染。
- 易于嵌入 —— 任何页面(落地页、背景、演示)都可直接使用。
- 适合作为环境 UI 背景 —— 展示了在恰当使用时,纯 JS + Canvas 能达到的视觉效果。