(使用🖼️表情包图片学习)如何使用🧠AI创建🎨3D动画(React Three Fiber vs Three.js vs A-Frame + GSAP)
Source: Dev.to
引言
最近,我一直在开发我的脑力训练应用 Muscle Brain。
- 我的应用 DEV 文章: 🚀 我是如何发布 Chrome 扩展的 (💪🧠 Muscle Brain v4)
上一次,我为该应用搭建了一个网站,并使用 GSAP 制作了 2D 动画。
- 我的网站 DEV 文章: 🧐 我创建了一个你可能会盯着看的网页动画 (GSAP) 🎨
现在我想学习 3D 并把动画从 2D 转换为 3D。学习 3D 的过程比我预想的要更具挑战性,因为涉及了许多新概念。让我们一起通过表情包图片边玩边学,逐步掌握 3D 吧! 🚀
3D 网页 与 2D 网页 的区别
3D 能提供更沉浸、更真实的动画体验,但学习曲线比 2D 陡峭。主要区别如下:
| 概念 | 2D 网页 | 3D 网页 |
|---|---|---|
| 难度 | 简单 | 困难 |
| 坐标轴 | X, Y | X, Y, Z |
| 相机 | 无 | 有 |
| 光照 | 无 | 有 |
| 着色方式 | CSS | Material |
- 坐标轴:2D 只使用 X(水平)和 Y(垂直)。3D 额外加入 Z(深度),可以让物体远近不同。
- 相机:2D 不需要相机,所有内容都是可见的。3D 需要相机并设置位置、旋转和视野(FOV),相机后面的物体不可见。
- 光照:在 3D 中必须有光源,否则材质会呈现全黑。
- 材质:3D 使用材质并拥有 metalness(0 = 塑料,1 = 金属)和 roughness(0 = 镜面,1 = 哑光)等属性。CSS 仍然用于 canvas 周围的 UI 布局。

重要的 3D 术语
下面列出了在使用 Three.js(或其封装库)时会经常碰到的关键词汇。
| 词汇 | 含义 |
|---|---|
| Scene | 承载所有对象的画布 |
| Camera | 你的眼睛;决定场景的哪一部分可见 |
| Render | 从相机视角绘制场景 |
| Geometry | 对象的形状 |
| Material | 外观(颜色、纹理等) |
| Mesh | 由几何体 + 材质组合而成的 3D 对象 |

Three.js vs React Three Fiber vs A‑Frame
这三种库都对 WebGL 进行封装,使 3D 开发更简单,但它们面向的工作流不同。
Three.js
React Three Fiber (r3f)
A‑Frame
对比表
| 特性 | Three.js | React Three Fiber | A‑Frame |
|---|---|---|---|
| 难度 | 困难 | 中等 | 简单 |
| 代码风格 | 面向对象 | React 组件 | HTML 组件 |
| 框架要求 | 原生 JS / 任意 | 仅 React | 原生 JS / 任意 |
| 最佳适用 | 需要最大控制、非 React 项目 | React 开发者 | 初学者、VR/AR 项目 |
这三者都可以在 Node.js 环境下使用。React Three Fiber 需要 React,而 Three.js 与 A‑Frame 可配合普通 JavaScript/TypeScript 以及任意框架。
示例星系动画(CodePen)
我做了一个非常简易的星系动画,随机的星星从远处向相机靠近。星星会自行发光,所以不需要光源。使用的材质如下:
- React Three Fiber –
meshBasicMaterial - Three.js –
MeshBasicMaterial - A‑Frame –
shader: flat

React Three Fiber 代码示例(GSAP 动画)
下面的代码片段让每颗星星从远处位置 (z: -50) 在 3 秒内移动到靠近相机的位置 (z: 5),并无限循环。
// Animate the star using GSAP
// gsap.fromTo = animate FROM one value TO another value
gsap.fromTo(
ref.current.position, // What to animate (the star's position in 3D space)
{ z: -50 }, // Starting value: far away (50 units behind camera)
{
z: 5, // Ending value: close to camera (5 units in front)
duration: 3, // Animation takes 3 seconds
delay: 0, // No initial delay
repeat: -1, // Loop forever
ease: "none"
}
);