"文字,不再是平面的叹息,而是立体宇宙的低语。" ------某位三维诗人
在这篇教学旅程中,我们将用 Three.js 打造一场"图形与文字"的冒险:让 SVG 图像与字体摆脱二维的宿命,在三维空间中复活。
准备好了吗?一起来跳进这片三维的墨水海洋吧!
✍️ 第一章:文字是可以雕刻的
🧩 工具:TextGeometry
与 FontLoader
Three.js 提供了内建的几何体来把字体变成 Mesh,核心两个角色:
FontLoader
:负责加载.json
字体文件(注意,不是.ttf
,需要先转换)TextGeometry
:把文字变成真正的几何体
🔨 示例代码:立体文字 Hello World
javascript
import * as THREE from 'three';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js';
const loader = new FontLoader();
loader.load('/fonts/helvetiker_regular.typeface.json', (font) => {
const geometry = new TextGeometry('Hello 3D!', {
font: font,
size: 1,
height: 0.3,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 0.03,
bevelSize: 0.02,
bevelSegments: 5,
});
const material = new THREE.MeshStandardMaterial({ color: 0xff5500 });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
});
💡 灵感提示:
- 字体文件
.typeface.json
可通过 facetype.js 在线工具转换。 bevel
可以让文字更"高级",就像雕刻了一道边缘。
🖼️ 第二章:SVG,二维图像的起义
你手上的 SVG 图标再也不用死守网页的一角,它们可以飞入三维空间,成为 Mesh、墙壁、甚至是三维打印模型的前身!
🧰 工具:SVGLoader
ini
import { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader.js';
const loader = new SVGLoader();
loader.load('/shapes/logo.svg', (data) => {
const paths = data.paths;
const group = new THREE.Group();
paths.forEach((path) => {
const shapes = SVGLoader.createShapes(path);
shapes.forEach((shape) => {
const geometry = new THREE.ExtrudeGeometry(shape, {
depth: 0.2,
bevelEnabled: false,
});
const material = new THREE.MeshStandardMaterial({
color: path.color || 0x006699,
side: THREE.DoubleSide,
});
const mesh = new THREE.Mesh(geometry, material);
group.add(mesh);
});
});
scene.add(group);
});
🧠 原理小讲堂
SVG 本质是由路径组成的,每条路径可以解释为一个"轮廓"。通过 createShapes()
,我们把路径变成"封闭轮廓",再用 ExtrudeGeometry
让它们"长"出厚度。
🎢 第三章:路径上的旅行者
让一个对象沿 SVG 路径运动,是一种浪漫的动画方式,仿佛一粒粒代码沙尘在路径中流淌。
ini
const points = shape.getPoints(100); // 从 shape 获取路径点
const curve = new THREE.CatmullRomCurve3(points.map(p => new THREE.Vector3(p.x, p.y, 0)));
// 动画对象
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(0.1),
new THREE.MeshStandardMaterial({ color: 0xff0000 })
);
scene.add(sphere);
// 在 render 中更新位置
let t = 0;
function animate() {
requestAnimationFrame(animate);
t += 0.001;
if (t > 1) t = 0;
const pos = curve.getPoint(t);
sphere.position.copy(pos);
renderer.render(scene, camera);
}
animate();
🎮 动画小贴士
- 使用
CatmullRomCurve3
可以平滑插值路径点。 - 如果需要旋转对象朝向路径,可结合
.getTangent(t)
。
🔮 第四章:一些彩蛋灵感
- 🎭 把字体挤出(extrude)后加上透明玻璃材质,做出"水晶文字"
- 🔄 给 SVG Mesh 加上
rotateY
动画,变成 UI loading 标志 - 🧊 配合环境光和
MeshPhysicalMaterial
,实现金属浮雕风格的 Logo - 🔁 把 SVG 路径转为
THREE.CurvePath
,用粒子跟随
📚 小结:二维图像的三维反叛
Three.js 不仅能让你渲染模型和相机运动,它还能让你把看似简单的字体与 SVG,变成动人的三维艺术。
"每一个字母,都是三维世界的砖块;每一条路径,都是想象力的高速公路。"