「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」
背景
上一篇文章(用three.js实现掘金红包封面-3D旋转LOGO)我们实现了3D旋转LOGO,本篇文章我准备实现中文和titleSVG,接下来我就来实现它吧!
技术
typescript- threejs
threejs知识点
- SVGLoader
- TTFLoader
- Font
- Group
实现 掘金title
为了实现掘金title我们要获取title.svg文件,这个很好获取,加开掘金首页,打开控制台,找到logo的img就可以看见了,如下图:
准备
代码
1. 引入SVGLoader加载器
import { SVGLoader } from "three/examples/jsm/loaders/SVGLoader";
2. 实现 掘金title
setTitleGroup(): void {
const loader = new SVGLoader();
loader.load(
"/assets/imgs/title.svg",
(data) => {
const paths = data.paths;
this.titleGroup = new THREE.Group();
for (let i = 0; i < paths.length; i++) {
const path = paths[i];
const material = new THREE.MeshLambertMaterial({
// color: path.color,
color: 0xffcea3,
side: THREE.DoubleSide,
depthWrite: false,
});
const shapes = SVGLoader.createShapes(path);
for (let j = 0; j < shapes.length; j++) {
const shape = shapes[j];
const geometry = new THREE.ShapeGeometry(shape);
const mesh = new THREE.Mesh(geometry, material);
this.titleGroup && this.titleGroup.add(mesh);
}
}
this.scene && this.titleGroup && this.scene.add(this.titleGroup);
},
// called when loading is in progresses
function (xhr) {
console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
},
// called when loading has errors
function (error) {
console.log("An error happened", error);
}
);
}
3. 居中方法
setCenter(group: THREE.Group): void {
const box = new THREE.Box3();
//通过传入的object3D对象来返回当前模型的最小大小,值可以使一个mesh也可以使group
box.expandByObject(group);
const mdlen = box.max.x - box.min.x;
const mdwid = box.max.z - box.min.z;
const mdhei = box.max.y - box.min.y;
const x1 = box.min.x + mdlen / 2;
const y1 = box.min.y + mdhei / 2;
const z1 = box.min.z + mdwid / 2;
group.position.set(-x1, -y1, -z1);
}
4. 位子设置
this.titleGroup.scale.set(0.2, 0.2, 0.2);
this.titleGroup.rotateX(Math.PI);
this.setCenter(this.titleGroup);
this.titleGroup.position.y = 70;
效果
实现中文("恭喜发财,大吉大利")
threejs显示中文,首先你要有一个拥有中文的字体,比如我用的是STHeiti.ttf,你有字体后还要加载字体,这个时候就要用TTFLoader加载器。
准备
STHeiti.ttf字体
代码
1. 引入TTFLoader加载器
import { TTFLoader } from "three/examples/jsm/loaders/TTFLoader";
2. 引入ttf转font类
import { Font, FontLoader } from "three/examples/jsm/loaders/FontLoader";
3. 实现文字
setTitle(): void {
const loader = new TTFLoader();
loader.load("/assets/fonts/STHeiti.ttf", (res) => {
if (this.scene) {
const json = new Font(res);
const text = "恭喜发财,大吉大利";
const font = new TextGeometry(text, {
font: json,
size: 4, //字体大小
height: 0.01, // 挤出文本的厚度
curveSegments: 12, // 曲线上点的数量。默认值为12
bevelEnabled: true, // 是否开启斜角,默认为false
bevelThickness: 0.5, // 文本上斜角的深度,默认值为20
bevelSize: 0.03, //斜角与原始文本轮廓之间的延伸距离。默认值为8
bevelSegments: 3, // 斜角的分段数。默认值为3
});
font.center();
const material = new THREE.MeshLambertMaterial({
color: 0xffcea3,
});
this.title = new THREE.Mesh(font, material);
this.title.position.set(0, 50, 0);
this.scene.add(this.title);
}
});
}
效果
本文效果
整体效果
结合上两篇文章的旋转文字环,整体效果如下: