当你在会议室里为需求细节争论不休时,智慧工厂的数字孪生正同步着每一条产线的实时脉搏;当你对着二维平面图脑补空间布局时,智慧小区的三维模型已在虚拟世界精准复刻每一扇窗的采光角度;当你在 CAD 里反复调整参数时,数字孪生城市的交通流正实时映射每辆车的行驶轨迹。
Taimili 艾米莉 ( 一款专业的 GitHub star 管理和github 加星涨星工具taimili.com )
艾米莉 是一款优雅便捷的 GitHub star 管理和github 加星涨星工具,基于 PHP & javascript 构建, 能对github 得 star fork follow watch 管理和提升,最适合github 的深度用户
作者:开源之眼
链接:juejin.cn/post/759282…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
从机械臂的 3D 仿真预演十万次零误差运动路径,到可交互 3D 引擎让客户直观拆解每一个齿轮;从 AR 动态指引覆盖所有售后故障点,到 VR 漫游让业主提前 "推开" 设计的门窗;从光影引擎精准计算午后 3 点的温柔折射,到材质参数的实时可视化调整 ——Web3D 正在重构我们与数字世界的交互方式。
对前端开发者而言,从 React 转向 Web3D 从来不是换条赛道,而是打开全新维度。正如韩老师所说:再牛的程序员都是从小白起步,既然选择出发,便全心投入深耕技术。下面这份 Three.js 入门指南,带你快速踏入三维开发的大门。
核心工具与文档
Three.js 作为 Web3D 开发的核心工具,其官方文档支持中文切换,所有 API 都能在文档中快速检索。只需掌握场景、相机、物体、渲染器四大基础组件,就能搭建起第一个 3D 应用。
基础核心:搭建你的第一个 3D 场景
1. 场景(Scene)
场景是 Three.js 的核心容器,相当于 3D 世界的 "舞台"—— 用于放置物体、灯光和相机,是所有可视化元素的承载基础。
javascript
运行
import * as THREE from "three";
// 创建3D场景
const scene = new THREE.Scene();
2. 相机(Camera)
相机决定了我们观察 3D 世界的视角,就像人的眼睛。常用的透视相机(PerspectiveCamera)模拟人眼成像原理,通过四个参数定义观察范围:
javascript
运行
// 创建透视相机
const camera = new THREE.PerspectiveCamera(
75, // 视野角度(单位:度)
window.innerWidth / window.innerHeight, // 宽高比(与窗口保持一致)
0.1, // 近截面(最近可见距离)
1000 // 远截面(最远可见距离)
);
// 设置相机位置(x, y, z轴坐标)
camera.position.set(0, 0, 10);
// 将相机添加到场景
scene.add(camera);
3. 物体(Cube)
3D 物体由几何体(Geometry)和材质(Material)组成。以立方体为例,先定义形状尺寸,再设置外观样式,最后组合成可渲染的网格对象:
javascript
运行
// 1. 创建几何体(长、宽、高均为1)
const cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
// 2. 创建材质(基础网格材质,黄色)
const cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
// 3. 组合几何体与材质,创建立方体对象
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 4. 将立方体添加到场景
scene.add(cube);
4. 渲染器(Renderer)
渲染器负责将场景和相机的信息渲染到页面上,本质是创建一个 Canvas 元素并插入到 DOM 中:
javascript
运行
// 初始化WebGL渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染尺寸(与窗口大小一致)
renderer.setSize(window.innerWidth, window.innerHeight);
// 将渲染结果(Canvas)添加到页面body
document.body.appendChild(renderer.domElement);
// 执行渲染:通过相机拍摄场景并呈现
renderer.render(scene, camera);
此时你会看到一个平面黄色方块 —— 要实现真正的 3D 交互,还需要添加控制器和辅助工具。
进阶交互:让 3D 世界 "活" 起来
1. 轨道控制器(OrbitControls)
添加轨道控制器后,可通过鼠标拖拽旋转视角、滚轮缩放,实现环绕观察效果,让平面图形秒变 3D 物体:
javascript
运行
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 创建控制器(绑定相机和渲染画布)
const controls = new OrbitControls(camera, renderer.domElement);
// 开启阻尼效果,让操作更平滑
controls.enableDamping = true;
// 定义渲染循环函数
function render() {
// 更新控制器状态(确保阻尼效果生效)
controls.update();
// 重复渲染下一帧
renderer.render(scene, camera);
requestAnimationFrame(render);
}
// 启动渲染循环
render();
2. 坐标轴辅助器
添加坐标轴辅助器可直观看到 3D 坐标系(红色 X 轴、绿色 Y 轴、蓝色 Z 轴),方便调试物体位置:
javascript
运行
// 创建坐标轴辅助器(轴长为5)
const axesHelper = new THREE.AxesHelper(5);
// 添加到场景
scene.add(axesHelper);
3. 物体变换:移动、缩放与旋转
通过修改物体的 position、scale、rotation 属性,可实现各类变换效果,支持单独设置或批量赋值:
javascript
运行
// 1. 移动(x轴移动3个单位)
cube.position.x = 3;
// 批量设置位置(x, y, z)
cube.position.set(3, 1, 2);
// 2. 缩放(x轴3倍、y轴2倍、z轴1倍)
cube.scale.set(3, 2, 1);
// 单独设置x轴缩放
cube.scale.x = 4;
// 3. 旋转(x轴旋转45度,弧度制:Math.PI/4)
cube.rotation.x = Math.PI / 4;
// 批量设置旋转(x, y, z, 顺序)
cube.rotation.set(Math.PI/4, 0, 0, "XZY");
4. 动画实现:让物体动起来
方式 1:requestAnimationFrame 手动控制
利用浏览器帧循环 API,实现匀速运动或周期性动画:
javascript
运行
function render(time) {
// time为时间戳,转换为秒并取余(实现0-5秒循环)
let t = (time / 1000) % 5;
// x轴随时间移动(0-5单位循环)
cube.position.x = t;
// 持续渲染
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
方式 2:Clock 时钟工具
Three.js 内置 Clock 工具,可精准获取时间间隔,避免手动计算误差:
javascript
运行
// 创建时钟对象
const clock = new THREE.Clock();
function render() {
// 获取时钟运行总时长
let time = clock.getElapsedTime();
// 获取两次渲染的时间间隔(约16ms/帧)
let deltaTime = clock.getDelta();
let t = time % 5;
cube.position.x = t;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
方式 3:GSAP 动画库(推荐)
GSAP(GreenSock Animation Platform)提供更强大的动画控制,支持缓动效果、循环、延迟等功能,集成简单高效:
javascript
运行
// 导入GSAP库
import gsap from "gsap";
// 1. 位置动画:x轴从0到5,5秒完成,往返循环
const animate1 = gsap.to(cube.position, {
x: 5,
duration: 5,
ease: "power1.inOut", // 缓动效果
repeat: -1, // 无限循环(-1表示循环)
yoyo: true, // 往返运动
delay: 2, // 延迟2秒启动
onStart: () => console.log("动画开始"),
onComplete: () => console.log("动画完成")
});
// 2. 旋转动画:x轴旋转360度(2π弧度)
gsap.to(cube.rotation, { x: 2 * Math.PI, duration: 5 });
// 双击暂停/恢复动画
window.addEventListener("dblclick", () => {
animate1.isActive() ? animate1.pause() : animate1.resume();
});
// 保持渲染循环
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
实用功能:提升开发体验
1. 窗口自适应
监听窗口尺寸变化,实时更新相机和渲染器设置,避免画面拉伸:
javascript
运行
window.addEventListener("resize", () => {
// 更新相机宽高比
camera.aspect = window.innerWidth / window.innerHeight;
// 刷新相机投影矩阵
camera.updateProjectionMatrix();
// 更新渲染器尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 设置像素比(适配高清屏幕)
renderer.setPixelRatio(window.devicePixelRatio);
});
2. 全屏切换
双击画布实现全屏 / 退出全屏功能,提升沉浸式体验:
javascript
运行
window.addEventListener("dblclick", () => {
const fullScreenElement = document.fullscreenElement;
if (!fullScreenElement) {
// 进入全屏(渲染画布元素)
renderer.domElement.requestFullscreen();
} else {
// 退出全屏
document.exitFullscreen();
}
});
3. 图形化调试(dat.GUI)
通过 dat.GUI 创建可视化控制面板,实时调整物体参数,无需修改代码重新运行:
javascript
运行
// 导入dat.GUI
import * as dat from "dat.gui";
// 创建GUI实例
const gui = new dat.GUI();
// 1. 控制x轴位置(0-5,步长0.01)
gui.add(cube.position, "x")
.min(0)
.max(5)
.step(0.01)
.name("移动X轴")
.onChange(value => console.log("X轴位置:", value));
// 2. 控制物体颜色
const params = {
color: "#ffff00",
// 自定义按钮事件:启动运动
startMove: () => {
gsap.to(cube.position, { x: 5, duration: 2, yoyo: true, repeat: -1 });
}
};
gui.addColor(params, "color").onChange(value => {
cube.material.color.set(value);
});
// 3. 控制物体可见性
gui.add(cube, "visible").name("是否显示");
// 4. 创建文件夹分类
const folder = gui.addFolder("立方体设置");
// 控制线框模式
folder.add(cube.material, "wireframe").name("线框模式");
// 绑定自定义事件
folder.add(params, "startMove").name("启动运动");
结语
前端的世界从不局限于 Vue 与 React 的框架之争,当 WebGL 成为下一代前端的基础设施,当元宇宙、数字孪生、AR/VR 等技术逐渐落地,Web3D 正成为开发者不可或缺的技能。
从二维到三维,不仅是技术栈的拓展,更是思维方式的升级。愿你在 Three.js 的三维坐标系中,探索更多可能,征服属于前端开发者的星辰大海。