手记

如何创造永无止境的乐趣(🎢RollerCoaster.js + React Three Fiber + AI)

更新(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次起伏

可以这样理解轨道生成的原理:
想象从一个简单的圆形轨道(类似赛车跑道)开始,然后:

  1. X 方程增加水平方向的扭转(左右摆动)
  2. Y 方程增加垂直方向的坡道(上下运动)
  3. 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 实现了这个项目。在 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 示例来对比 SvelteReact 的区别,但由于 ThrelteCodePen 中无法使用,转而尝试了 StackBlitz。虽然 ThrelteStackBlitz 中可以运行,但启动时间较长。以下是相关代码示例:

默认过山车 ↓

彩虹过山车 ↓

未来更新计划

基于现有代码,我计划进行以下功能扩展:😆

  • 为过山车和星星添加更丰富的动画效果
  • 增强过山车和星星的物理模拟
  • 开发可视化轨道编辑器,让用户无需编写代码即可自定义轨道
更多动画与 AI 资源

我之前写过关于 2D/3D 动画的文章,如果你想深入了解这个领域,可以参考以下内容:

以下是我关于 AI 技术的一些分享:

结语

乘坐过山车是一种充满乐趣的刺激体验。虽然现实中无法无限次乘坐,但现在我们可以通过虚拟技术尽情享受这种乐趣。动画制作本身就是一个极其有趣的创作过程,我期待能在这方面继续深入探索!😊

希望本文的内容对你有所启发。如果你对 2D/3D 动画有任何好点子或见解,欢迎在评论区分享!⬇️

0人推荐
随时随地看视频
慕课网APP