three-base 1.0.62 → 1.0.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/lib/ApngTexture.js +61 -0
  2. package/lib/ApngTextureManage.js +87 -0
  3. package/lib/EventMesh.js +59 -0
  4. package/lib/ExtrudeMesh.js +362 -0
  5. package/lib/FPScontrol.js +170 -0
  6. package/lib/InstancedGroupMesh.js +63 -0
  7. package/lib/KeyFrameAnimation.js +78 -0
  8. package/lib/PlaneText.js +30 -0
  9. package/lib/PointLight.js +64 -0
  10. package/lib/Sky/Sky.js +28 -0
  11. package/lib/Text3D/Text3D.js +61 -0
  12. package/lib/Text3D/Text3D.ts +3 -3
  13. package/lib/Text3D/fontController.js +200 -0
  14. package/lib/ThreeBase.js +393 -0
  15. package/lib/ThreeMouse.js +357 -0
  16. package/lib/Transition.js +193 -0
  17. package/lib/index.d.ts +22 -0
  18. package/lib/keyContorls.js +98 -0
  19. package/lib/lib/ApngTexture.d.ts +13 -0
  20. package/lib/lib/ApngTextureManage.d.ts +18 -0
  21. package/lib/lib/EventMesh.d.ts +18 -0
  22. package/lib/lib/ExtrudeMesh.d.ts +111 -0
  23. package/lib/lib/FPScontrol.d.ts +44 -0
  24. package/lib/lib/InstancedGroupMesh.d.ts +10 -0
  25. package/lib/lib/KeyFrameAnimation.d.ts +25 -0
  26. package/lib/lib/PlaneText.d.ts +37 -0
  27. package/lib/lib/PointLight.d.ts +13 -0
  28. package/lib/lib/Sky/Sky.d.ts +13 -0
  29. package/lib/lib/Text3D/Text3D.d.ts +20 -0
  30. package/lib/lib/Text3D/fontController.d.ts +59 -0
  31. package/lib/lib/ThreeBase.d.ts +59 -0
  32. package/lib/lib/ThreeMouse.d.ts +39 -0
  33. package/lib/lib/Transition.d.ts +45 -0
  34. package/lib/lib/keyContorls.d.ts +25 -0
  35. package/lib/lib/planeModal1/PlaneModal1.d.ts +32 -0
  36. package/lib/lib/shaders.d.ts +17 -0
  37. package/lib/lib/spriteModal1/SpriteModal1.d.ts +31 -0
  38. package/lib/lib/threeLoader.d.ts +20 -0
  39. package/lib/lib/threeUtils.d.ts +41 -0
  40. package/lib/lib/type.d.ts +0 -0
  41. package/lib/planeModal1/PlaneModal1.js +104 -0
  42. package/lib/shaders.js +245 -0
  43. package/lib/spriteModal1/SpriteModal1.js +109 -0
  44. package/lib/threeLoader.js +110 -0
  45. package/lib/threeUtils.js +179 -0
  46. package/lib/type.js +10 -0
  47. package/package.json +2 -4
@@ -0,0 +1,170 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2022-05-04 23:01:36
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2022-06-06 13:32:08
6
+ */
7
+ import { Clock, EventDispatcher, Vector3 } from "three";
8
+ import { Capsule } from "three/examples/jsm/math/Capsule";
9
+ import { Octree } from "three/examples/jsm/math/Octree";
10
+ import { clamp, degToRad } from "three/src/math/MathUtils";
11
+ /**
12
+ * 第一人称控制器
13
+ *
14
+ * @export
15
+ * @class FPScontrol
16
+ * @extends {EventDispatcher}
17
+ */
18
+ export default class FPScontrol extends EventDispatcher {
19
+ canvas;
20
+ constructor(camera, canvas) {
21
+ super();
22
+ // 相机对象
23
+ this.camera = camera;
24
+ this.camera.rotation.order = 'YXZ';
25
+ this.canvas = canvas;
26
+ this.init(canvas);
27
+ }
28
+ // 是否启用
29
+ enable = false;
30
+ GRAVITY = 30; // 重力
31
+ STEPS_PER_FRAME = 5; // 速度
32
+ camera;
33
+ // 世界八叉树对象
34
+ worldOctree = new Octree();
35
+ // 用户自己的碰撞体积
36
+ playerCollider = new Capsule(new Vector3(0, 0.35, 0), new Vector3(0, 1, 0), 0.35);
37
+ // 时钟对象
38
+ clock = new Clock();
39
+ playerVelocity = new Vector3();
40
+ playerDirection = new Vector3();
41
+ playerOnFloor = false;
42
+ mouseTime = 0;
43
+ isMousedown = false;
44
+ keyStates = {};
45
+ init(canvas) {
46
+ this.playerCollider.end.set(0, 1, 0);
47
+ document.addEventListener('keydown', this.keydown);
48
+ document.addEventListener('keyup', this.keyup);
49
+ canvas.addEventListener('pointerdown', this.mousedown);
50
+ document.addEventListener('pointerup', this.mouseup);
51
+ document.body.addEventListener('pointermove', this.mousemove);
52
+ this.enable = true;
53
+ }
54
+ keydown = (event) => {
55
+ this.keyStates[event.code] = true;
56
+ };
57
+ keyup = (event) => {
58
+ this.keyStates[event.code] = false;
59
+ };
60
+ mousedown = () => {
61
+ this.isMousedown = true;
62
+ this.mouseTime = performance.now();
63
+ };
64
+ mouseup = () => {
65
+ this.isMousedown = false;
66
+ };
67
+ mousemove = (event) => {
68
+ if (this.enable && this.isMousedown) {
69
+ this.camera.rotation.y -= event.movementX / 500;
70
+ this.camera.rotation.x -= event.movementY / 500;
71
+ }
72
+ };
73
+ // 设置 八叉树 节点
74
+ fromGraphNode(object3d) {
75
+ this.worldOctree.fromGraphNode(object3d);
76
+ }
77
+ // 获取前进的向量
78
+ getForwardVector = () => {
79
+ this.camera.getWorldDirection(this.playerDirection);
80
+ this.playerDirection.y = 0;
81
+ this.playerDirection.normalize();
82
+ return this.playerDirection;
83
+ };
84
+ // 获取 后退的向量
85
+ getSideVector = () => {
86
+ this.camera.getWorldDirection(this.playerDirection);
87
+ this.playerDirection.y = 0;
88
+ this.playerDirection.normalize();
89
+ this.playerDirection.cross(this.camera.up);
90
+ return this.playerDirection;
91
+ };
92
+ // 玩家移动控制器
93
+ controls = (deltaTime) => {
94
+ const speedDelta = deltaTime * (this.playerOnFloor ? 25 : 8);
95
+ if (this.keyStates['KeyW']) {
96
+ this.playerVelocity.add(this.getForwardVector().multiplyScalar(speedDelta));
97
+ }
98
+ if (this.keyStates['KeyS']) {
99
+ this.playerVelocity.add(this.getForwardVector().multiplyScalar(-speedDelta));
100
+ }
101
+ if (this.keyStates['KeyA']) {
102
+ this.playerVelocity.add(this.getSideVector().multiplyScalar(-speedDelta));
103
+ }
104
+ if (this.keyStates['KeyD']) {
105
+ this.playerVelocity.add(this.getSideVector().multiplyScalar(speedDelta));
106
+ }
107
+ if (this.playerOnFloor) {
108
+ if (this.keyStates['Space']) {
109
+ this.playerVelocity.y = 15;
110
+ }
111
+ }
112
+ };
113
+ // 更新玩家的位置
114
+ updatePlayer = (deltaTime) => {
115
+ let damping = Math.exp(-4 * deltaTime) - 1;
116
+ if (!this.playerOnFloor) {
117
+ this.playerVelocity.y -= this.GRAVITY * deltaTime;
118
+ damping *= 0.1;
119
+ }
120
+ this.playerVelocity.addScaledVector(this.playerVelocity, damping);
121
+ const deltaPosition = this.playerVelocity.clone().multiplyScalar(deltaTime);
122
+ this.playerCollider.translate(deltaPosition);
123
+ this.playerCollisions();
124
+ this.camera.position.copy(this.playerCollider.end);
125
+ this.camera.position.y += 1;
126
+ this.camera.rotation.x = clamp(this.camera.rotation.x, degToRad(-20), degToRad(20));
127
+ };
128
+ // 玩家的碰撞检测
129
+ playerCollisions() {
130
+ const result = this.worldOctree.capsuleIntersect(this.playerCollider);
131
+ this.playerOnFloor = false;
132
+ if (result) {
133
+ this.playerOnFloor = result.normal.y > 0;
134
+ if (!this.playerOnFloor) {
135
+ this.playerVelocity.addScaledVector(result.normal, -result.normal.dot(this.playerVelocity));
136
+ }
137
+ this.playerCollider.translate(result.normal.multiplyScalar(result.depth));
138
+ }
139
+ }
140
+ // 更新控制器的位置
141
+ teleportPlayerIfOob = () => {
142
+ if (this.camera.position.y <= -10) {
143
+ this.playerCollider.start.set(0, 0.35, 0);
144
+ this.playerCollider.end.set(0, 1, 10);
145
+ this.playerCollider.radius = 0.35;
146
+ this.camera.position.copy(this.playerCollider.end);
147
+ // this.camera.position.set(0, 3, 0);
148
+ }
149
+ };
150
+ // 更新
151
+ update() {
152
+ if (this.enable) {
153
+ const deltaTime = Math.min(0.05, this.clock.getDelta()) / this.STEPS_PER_FRAME;
154
+ for (let i = 0; i < this.STEPS_PER_FRAME; i++) {
155
+ this.controls(deltaTime);
156
+ this.updatePlayer(deltaTime);
157
+ this.teleportPlayerIfOob();
158
+ }
159
+ }
160
+ }
161
+ // 销毁事件
162
+ disposer() {
163
+ this.enable = false;
164
+ document.removeEventListener('keydown', this.keydown);
165
+ document.removeEventListener('keyup', this.keyup);
166
+ this.canvas.removeEventListener('pointerdown', this.mousedown);
167
+ document.removeEventListener('pointerup', this.mouseup);
168
+ document.body.removeEventListener('pointermove', this.mousemove);
169
+ }
170
+ }
@@ -0,0 +1,63 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2023-02-21 09:55:52
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2023-02-26 14:42:21
6
+ */
7
+ import * as THREE from 'three';
8
+ // 模型组转成 实例对象
9
+ export default class InstancedGroupMesh extends THREE.Mesh {
10
+ isInstancedGroupMesh = true;
11
+ count = 0;
12
+ meshCollect = {};
13
+ instanceCollect = {};
14
+ static matrix = new THREE.Matrix4();
15
+ constructor(group, count) {
16
+ super();
17
+ this.count = count;
18
+ const { meshCollect, instanceCollect } = this;
19
+ group.updateMatrixWorld(true);
20
+ // collect all mesh counts, in case there are more than one copy of the same mesh in this group
21
+ group.traverse((obj) => {
22
+ const mesh = obj;
23
+ if (mesh.isMesh) {
24
+ mesh.matrixWorld.decompose(mesh.position, mesh.quaternion, mesh.scale);
25
+ mesh.rotation.setFromQuaternion(mesh.quaternion);
26
+ mesh.updateMatrix();
27
+ // same geometry and same material consider as the same mesh
28
+ const uuid = mesh.geometry.uuid + '/' + mesh.material.uuid;
29
+ if (meshCollect[uuid]) {
30
+ meshCollect[uuid].push(mesh);
31
+ }
32
+ else {
33
+ meshCollect[uuid] = [mesh];
34
+ }
35
+ }
36
+ else {
37
+ obj.position.set(0, 0, 0);
38
+ obj.scale.set(1, 1, 1);
39
+ obj.rotation.set(0, 0, 0);
40
+ }
41
+ });
42
+ // create all instances
43
+ Object.keys(meshCollect).forEach(uuid => {
44
+ const meshes = meshCollect[uuid];
45
+ const mesh = meshes[0];
46
+ const instancedMesh = new THREE.InstancedMesh(mesh.geometry, mesh.material, meshes.length * count);
47
+ instanceCollect[uuid] = instancedMesh;
48
+ this.add(instancedMesh);
49
+ });
50
+ }
51
+ setMatrixAt(index, matrix) {
52
+ Object.keys(this.meshCollect).forEach(uuid => {
53
+ const instancedMesh = this.instanceCollect[uuid];
54
+ const collect = this.meshCollect[uuid];
55
+ collect.forEach((mesh, i) => {
56
+ InstancedGroupMesh.matrix.copy(mesh.matrix);
57
+ InstancedGroupMesh.matrix.premultiply(matrix);
58
+ instancedMesh.setMatrixAt(collect.length * index + i, InstancedGroupMesh.matrix);
59
+ instancedMesh.instanceMatrix.needsUpdate = true;
60
+ });
61
+ });
62
+ }
63
+ }
@@ -0,0 +1,78 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2023-02-16 00:22:31
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2023-02-16 19:08:55
6
+ */
7
+ import { last } from "lodash";
8
+ import { BufferAttribute, Line, LineBasicMaterial, Object3D } from "three";
9
+ import threeUtils from "./threeUtils";
10
+ // 关键帧动画对象
11
+ export default class KeyframeAnimation extends Object3D {
12
+ constructor(props) {
13
+ super();
14
+ // 速度调整
15
+ this.speedScale = props.speedScale || 1;
16
+ // 设置关键帧对象数组
17
+ this.setKeyframes(props.keyframes);
18
+ // 设置对象
19
+ this.setObject3D(props.object3d);
20
+ }
21
+ // 速度调整
22
+ speedScale = 1;
23
+ // 需要需要移动的对象
24
+ object3d;
25
+ //路径辅助线
26
+ halperLine = new Line(undefined, new LineBasicMaterial({ color: "#f00" }));
27
+ // 关键帧数组
28
+ keyframes = [];
29
+ // 设置需要移动的对象
30
+ setObject3D(object3d) {
31
+ this.object3d = object3d;
32
+ if (threeUtils.isDev) {
33
+ this.children = [object3d, this.halperLine];
34
+ }
35
+ else {
36
+ this.children = [object3d];
37
+ }
38
+ }
39
+ // 获取单个关键帧
40
+ getKeyframe(i) {
41
+ return this.keyframes[i];
42
+ }
43
+ // 设置单个关键帧
44
+ setKeyframe(i, keyframe) {
45
+ this.keyframes[i] = keyframe;
46
+ this.setKeyframes(this.keyframes);
47
+ }
48
+ //设置全部关键帧
49
+ setKeyframes(keyframes) {
50
+ this.keyframes = keyframes;
51
+ const position = [];
52
+ keyframes.map(k => {
53
+ position.push(k.position.x);
54
+ position.push(k.position.y);
55
+ position.push(k.position.z);
56
+ });
57
+ this.halperLine.geometry.setAttribute("position", new BufferAttribute(new Float32Array(position), 3, false));
58
+ }
59
+ // 更具关键帧的信息更新 对象的位置
60
+ update() {
61
+ const { _timeTemp } = threeUtils;
62
+ const maxtimetemp = last(this.keyframes).timeTemp;
63
+ const currentTime = _timeTemp % maxtimetemp;
64
+ const currentKeyframeIndex = this.keyframes.findIndex(k => currentTime < k.timeTemp);
65
+ const startKeyframe = this.keyframes[currentKeyframeIndex - 1];
66
+ const endKeyframe = this.keyframes[currentKeyframeIndex];
67
+ const progress = (currentTime - startKeyframe.timeTemp) / (endKeyframe.timeTemp - startKeyframe.timeTemp);
68
+ this.object3d.position.copy(endKeyframe.position).sub(startKeyframe.position).multiplyScalar(progress).add(startKeyframe.position);
69
+ this.object3d.scale.copy(endKeyframe.scale).sub(startKeyframe.scale).multiplyScalar(progress).add(startKeyframe.scale);
70
+ this.object3d.rotation.set((endKeyframe.rotation.x - startKeyframe.rotation.x) * progress + startKeyframe.rotation.x, (endKeyframe.rotation.y - startKeyframe.rotation.y) * progress + startKeyframe.rotation.y, (endKeyframe.rotation.z - startKeyframe.rotation.z) * progress + startKeyframe.rotation.z);
71
+ this.dispatchEvent({ type: "update" });
72
+ }
73
+ //更新关键帧的实例矩阵
74
+ updateMatrix() {
75
+ this.update();
76
+ super.updateMatrix();
77
+ }
78
+ }
@@ -0,0 +1,30 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2022-05-23 13:53:06
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2022-05-23 19:38:24
6
+ */
7
+ import { DoubleSide, Mesh, MeshBasicMaterial, PlaneGeometry, Vector3 } from "three";
8
+ import SpriteText from "three-spritetext";
9
+ export default class PlaneText extends Mesh {
10
+ constructor(text = "planeText") {
11
+ super(PlaneText.geometry);
12
+ this.set({ text });
13
+ }
14
+ type = "PlaneText";
15
+ static geometry = new PlaneGeometry(1, 1, 1, 1);
16
+ spriteText = new SpriteText("");
17
+ material = new MeshBasicMaterial({ transparent: true, side: DoubleSide, map: this.spriteText.material.map });
18
+ set(parame) {
19
+ for (let key in parame) {
20
+ //@ts-ignore
21
+ this.spriteText[key] = parame[key];
22
+ }
23
+ this.scale.copy(this.spriteText.scale);
24
+ this.scale.max(new Vector3(1, 1, 1));
25
+ this.material.map = this.spriteText.material.map;
26
+ }
27
+ get(prop) {
28
+ return this.spriteText[prop];
29
+ }
30
+ }
@@ -0,0 +1,64 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2022-05-18 16:02:55
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2022-06-23 21:02:45
6
+ */
7
+ import { Mesh, MeshBasicMaterial, PointLight as THREEPointLight, SphereGeometry } from "three";
8
+ import threeSpritetext from "three-spritetext";
9
+ import threeUtils from "./threeUtils";
10
+ /**
11
+ * 点光源
12
+ * @export
13
+ * @class PointLight
14
+ * @extends {THREEPointLight}
15
+ */
16
+ export default class PointLight extends THREEPointLight {
17
+ constructor(color = "#fff", intensity, distance, decay) {
18
+ super(color, intensity, distance, decay);
19
+ if (threeUtils.isDev) {
20
+ if (this.label) {
21
+ this.label.borderColor = color;
22
+ this.label.color = color;
23
+ this.label.scale.multiplyScalar(0.03);
24
+ }
25
+ }
26
+ }
27
+ sphere = threeUtils.isDev && (() => {
28
+ // 点光源辅助小球
29
+ const sphere = new SphereGeometry(0.1, 10, 10);
30
+ const materils = new MeshBasicMaterial({
31
+ color: this.color,
32
+ wireframe: true
33
+ });
34
+ const mesh = new Mesh(sphere, materils);
35
+ mesh.userData = {
36
+ cursor: "pointer"
37
+ };
38
+ mesh.addEventListener("mouseenter", () => {
39
+ if (this.label) {
40
+ this.label.visible = true;
41
+ }
42
+ });
43
+ mesh.addEventListener("mouseleave", () => {
44
+ if (this.label) {
45
+ this.label.visible = false;
46
+ }
47
+ });
48
+ this.add(mesh);
49
+ })();
50
+ label = threeUtils.isDev && (() => {
51
+ const label = new threeSpritetext("点光源");
52
+ label.renderOrder = Infinity;
53
+ label.backgroundColor = "rgba(0, 0, 0, 0.5)";
54
+ label.padding = 4;
55
+ label.borderRadius = 4;
56
+ label.borderWidth = 1;
57
+ label.position.set(0, 0.5, 0);
58
+ label.visible = false;
59
+ label.material.depthTest = false;
60
+ label.scale.multiplyScalar(0.001);
61
+ this.add(label);
62
+ return label;
63
+ })();
64
+ }
package/lib/Sky/Sky.js ADDED
@@ -0,0 +1,28 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2022-05-20 18:03:58
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2022-12-27 09:54:23
6
+ */
7
+ import { DoubleSide, Mesh, MeshBasicMaterial, SphereGeometry } from "three";
8
+ import threeLoader from "../threeLoader";
9
+ import blueskyJPG from "./blueSky.jpg";
10
+ /**
11
+ * 天空球
12
+ */
13
+ export default class Sky extends Mesh {
14
+ constructor() {
15
+ super(Sky.geometry);
16
+ }
17
+ static geometry = new SphereGeometry(500000, 100, 100);
18
+ material = new MeshBasicMaterial({
19
+ side: DoubleSide,
20
+ map: threeLoader.getTexture(blueskyJPG)
21
+ });
22
+ /**
23
+ *设置贴图
24
+ */
25
+ setMap(src) {
26
+ this.material.map = threeLoader.getTexture(src);
27
+ }
28
+ }
@@ -0,0 +1,61 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2022-06-14 09:48:00
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2023-04-07 21:52:03
6
+ */
7
+ import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js';
8
+ import { Mesh, MeshStandardMaterial } from "three";
9
+ import fontContorller from "./fontController";
10
+ // 3D文字模型
11
+ export default class Text3D extends Mesh {
12
+ constructor(text = "new Text3D()") {
13
+ super();
14
+ this.setText({ text });
15
+ }
16
+ // 字体的存储路径 例如 : "http://drm.gitee.io/three-base-font/simhei/字.js"
17
+ static path = "http://drm.gitee.io/three-base-font/";
18
+ material = new MeshStandardMaterial({
19
+ metalness: 0.8,
20
+ roughness: 0.5, // 粗糙度,值为0到1
21
+ });
22
+ // 配置
23
+ _config = {
24
+ text: "",
25
+ fontType: "simhei",
26
+ size: 1,
27
+ curveSegments: 10,
28
+ height: 0.1,
29
+ bevelEnabled: true,
30
+ bevelThickness: 0.02,
31
+ bevelSize: 0.015,
32
+ bevelOffset: 0,
33
+ bevelSegments: 3, //斜角分段
34
+ };
35
+ // 设置文字
36
+ setText(text3DProps) {
37
+ if (Object.keys(text3DProps).some(key => text3DProps[key] !== this._config[key])) {
38
+ Object.assign(this._config, text3DProps);
39
+ fontContorller.loadText({
40
+ fontBasePath: Text3D.path,
41
+ text: this._config.text,
42
+ fontType: this._config.fontType,
43
+ callback: THREEFont => {
44
+ this.geometry.dispose();
45
+ this.geometry = new TextGeometry(this._config.text || "", {
46
+ font: THREEFont,
47
+ size: this._config.size,
48
+ curveSegments: this._config.curveSegments,
49
+ height: this._config.height,
50
+ bevelEnabled: this._config.bevelEnabled,
51
+ bevelThickness: this._config.bevelThickness,
52
+ bevelSize: this._config.bevelSize,
53
+ bevelOffset: this._config.bevelOffset,
54
+ bevelSegments: this._config.bevelSegments, //斜角分段
55
+ });
56
+ this.geometry.center();
57
+ }
58
+ });
59
+ }
60
+ }
61
+ }
@@ -2,7 +2,7 @@
2
2
  * @Author: xiaosihan
3
3
  * @Date: 2022-06-14 09:48:00
4
4
  * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2022-06-14 10:01:13
5
+ * @Last Modified time: 2023-04-07 21:52:03
6
6
  */
7
7
 
8
8
  import { TextGeometry, TextGeometryParameters } from 'three/examples/jsm/geometries/TextGeometry.js';
@@ -59,7 +59,7 @@ export default class Text3D extends Mesh {
59
59
  // 设置文字
60
60
  setText(text3DProps: Text3DProps) {
61
61
 
62
- if (Object.keys(text3DProps).some(key => text3DProps[key] !== this._config[key])) {
62
+ if (Object.keys(text3DProps).some(key => text3DProps[key as keyof typeof text3DProps] !== this._config[key as keyof typeof this._config])) {
63
63
 
64
64
  Object.assign(this._config, text3DProps);
65
65
 
@@ -69,7 +69,7 @@ export default class Text3D extends Mesh {
69
69
  fontType: this._config.fontType,
70
70
  callback: THREEFont => {
71
71
  this.geometry.dispose();
72
- this.geometry = new TextGeometry(this._config.text, {
72
+ this.geometry = new TextGeometry(this._config.text || "", {
73
73
  font: THREEFont,
74
74
  size: this._config.size,
75
75
  curveSegments: this._config.curveSegments,