更新(2025/12/30):新增过山车噩梦模式😨
引言什么时候会让你感到兴奋和有趣?就我而言,目前我正沉迷于尝试各种最新、最潮的 IT 技术。但回想起童年时期,我觉得坐过山车才是真正有趣和刺激的体验。🎢 然而,真实的过山车转瞬即逝,就像短暂的梦境。为此,我编写了一套代码,让我们能够在家中无限享受过山车的刺激感!🚀
RollerCoaster.js🎢我为这个项目找到了一个完美的库——RollerCoaster.js。这是一个相对小众但十分专业的库。在官方的 Three.js 网站(最流行的 3D 库)上就有使用这个库的示例。
过山车演示 ↓
https://threejs.org/examples/webxr_vr_rollercoaster.html
过山车演示的 GitHub 仓库 ↓
https://github.com/mrdoob/three.js/blob/master/examples/webxr_vr_rollercoaster.html
这里是 RollerCoaster.js 的 GitHub 仓库:↓
https://github.com/mrdoob/three.js/blob/master/examples/jsm/misc/RollerCoaster.js
这个库的核心是 RollerCoasterGeometry 类,你可以用它轻松创建逼真的过山车轨道。↓
https://threejs.org/docs/#RollerCoasterGeometry
我在 AI 的协助下创建了一个带有初学者友好注释的过山车 CodePen 示例。这个示例基于官方的 Three.js 示例,但进行了简化以便于理解。我使用 React Three Fiber 来处理 3D 动画,它是 Three.js 的 React 封装库,能显著简化在 React 项目中的使用。
这个动画的一个有趣特性是过山车的物理行为:下坡时加速,上坡时减速。你可以通过以下代码段调整速度:
// 将速度限制在最小值和最大值之间(防止过慢或过快)
velocityRef.current = Math.max(0.00004, Math.min(0.0002, velocityRef.current));
轨道的形状是通过参数方程来定义的,这些方程使用了正弦和余弦函数:
const x = Math.sin(t * 3) * Math.cos(t * 4) * 50;
const y = Math.sin(t * 10) * 2 + Math.cos(t * 17) * 2 + 5;
const z = Math.sin(t) * Math.sin(t * 4) * 50;
t * 后面的数字控制了频率,即单位时间内波形或循环的次数:
- 更高的频率 = 更多的波/循环 → 更复杂的轨道
- 更低的频率 = 更少的波/循环 → 更平滑简单的轨道
以 Y 轴(垂直运动)为例:
const y = Math.sin(t * 10) * 2; // 每循环10次起伏
const y = Math.sin(t * 2) * 2; // 每循环只有2次起伏
可以这样理解轨道生成的原理:
想象从一个简单的圆形轨道(类似赛车跑道)开始,然后:
- X 方程增加水平方向的扭转(左右摆动)
- Y 方程增加垂直方向的坡道(上下运动)
- Z 方程增加深度方向的曲线(前后螺旋)
因此,更高的频率值会产生更复杂的轨道图案。
彩虹过山车🌈那么,如何让这个过山车变得更有趣、更刺激呢?😆 我们来给它加点料!我将轨道颜色改为彩虹色,并将背景设置为带有彩色星星的太空场景。通过 CSS 的 linear-gradient 创建基础太空氛围,再用 radial-gradient 添加雾状景深效果:
/* 🌌 深邃太空基底 - 简单的黑色到深紫色渐变 */
background: linear-gradient(to bottom, #000000 0%, #0d0019 100%);
/* 暗角效果:边缘暗,中心渐变为透明
- 创造深度和大气"雾"效果
- 非常暗,带有细微的紫色调 (10, 0, 20) = 近乎黑色
- 0.4 的不透明度 = 微妙、专业的氛围
*/
background: radial-gradient(
ellipse at center,
transparent 0%,
transparent 40%,
rgba(10, 0, 20, 0.4) 100%
);
你可以通过修改循环次数来调整星星的数量:
for (let i = 0; i < 500; i++) {
也可以通过修改 size 参数来调整星星的大小:
const size = Math.random() * 0.5 + 0.3; // 随机大小从 0.3 到 0.8
增加星星的数量和大小能够为整个场景营造出截然不同的氛围,让过山车体验更加梦幻。
过山车噩梦😨我还制作了一个噩梦版本的过山车。通过增加所有 t * 参数的值,我创建了更多起伏和更急的弯道,形成了极其刺激的轨道布局。同时提高了运行速度以增强惊险感。轨道颜色改为红黑渐变,CSS 渐变也调整为中央明亮边缘昏暗的恐怖效果。
为了学习比较,我还用 Svelte 实现了这个项目。在 Svelte 中,我使用 Threlte 来处理 3D 图形,它是 Three.js 的 Svelte 封装库。Svelte 相比 React 有几个显著优势:代码更简洁、打包体积更小、运行性能更优。
<!-- Svelte -->
// 声明状态
let velocity = 0.00004;
// 更新状态
velocity += 0.001; // 直接赋值即可!
// React
// 声明状态
const [velocity, setVelocity] = useState(0.00004);
// 更新状态
setVelocity(v => v + 0.001); // 需要 setter 函数
我原本计划制作默认和彩虹过山车的 CodePen 示例来对比 Svelte 和 React 的区别,但由于 Threlte 在 CodePen 中无法使用,转而尝试了 StackBlitz。虽然 Threlte 在 StackBlitz 中可以运行,但启动时间较长。以下是相关代码示例:
默认过山车 ↓
彩虹过山车 ↓
未来更新计划基于现有代码,我计划进行以下功能扩展:😆
- 为过山车和星星添加更丰富的动画效果
- 增强过山车和星星的物理模拟
- 开发可视化轨道编辑器,让用户无需编写代码即可自定义轨道
我之前写过关于 2D/3D 动画的文章,如果你想深入了解这个领域,可以参考以下内容:
- (通过🖼️表情包学习)如何使用🧠AI创建🎨3D动画(React Three Fiber vs Three.js vs A-Frame + GSAP)
- 🧐我创建了一个你可能会盯着看一会儿的网站动画(GSAP)🎨
以下是我关于 AI 技术的一些分享:
- 🧠如何让 Codex 像老伙计 Claude Code 一样提振你的情绪(重回"你说得完全正确!"的感觉)🤖
- 🤖🤖如何轻松免费地并行运行 AI(Git Worktree Runner)🧠🧠
- 🤖如何免费让 AI 更遵循你的指令(OpenSpec)📝
- 🧠如何更高效地免费使用 AI(Serena MCP)🧐
乘坐过山车是一种充满乐趣的刺激体验。虽然现实中无法无限次乘坐,但现在我们可以通过虚拟技术尽情享受这种乐趣。动画制作本身就是一个极其有趣的创作过程,我期待能在这方面继续深入探索!😊
希望本文的内容对你有所启发。如果你对 2D/3D 动画有任何好点子或见解,欢迎在评论区分享!⬇️
随时随地看视频