three-base 1.0.57 → 1.0.59

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.
@@ -90,9 +90,9 @@ export default class KeyframeAnimation extends Object3D {
90
90
 
91
91
  // 更具关键帧的信息更新 对象的位置
92
92
  update() {
93
- const { timeTemp } = threeUtils;
93
+ const { _timeTemp } = threeUtils;
94
94
  const maxtimetemp = last(this.keyframes)!.timeTemp;
95
- const currentTime = timeTemp % maxtimetemp;
95
+ const currentTime = _timeTemp % maxtimetemp;
96
96
 
97
97
  const currentKeyframeIndex = this.keyframes.findIndex(k => currentTime < k.timeTemp);
98
98
 
package/lib/ThreeBase.ts CHANGED
@@ -2,12 +2,12 @@
2
2
  * @Author: xiaosihan
3
3
  * @Date: 2021-12-20 13:38:22
4
4
  * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2023-03-30 11:00:20
5
+ * @Last Modified time: 2023-03-16 14:31:32
6
6
  */
7
7
 
8
8
  import elementResizeEvent from "element-resize-event";
9
9
  import { round } from "lodash";
10
- import { AxesHelper, EventDispatcher, GridHelper, LinearFilter, MOUSE, NoBlending, NormalBlending, Object3D, PerspectiveCamera, RGBAFormat, Scene, Texture, TOUCH, Vector2, Vector3, WebGLRenderer, WebGLRenderTarget } from "three";
10
+ import { AxesHelper, BufferGeometry, EventDispatcher, GridHelper, LinearFilter, Mesh, MeshBasicMaterial, MOUSE, NoBlending, NormalBlending, Object3D, PerspectiveCamera, RGBAFormat, Scene, Texture, TOUCH, Vector2, Vector3, WebGLRenderer, WebGLRenderTarget } from "three";
11
11
  import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
12
12
  import { generateUUID } from "three/src/math/MathUtils";
13
13
  import { clearShader, coptyShader, fullScreenMesh, gaussBlurShader, strokeShader } from "./shaders";
@@ -102,8 +102,7 @@ export default class ThreeBase extends EventDispatcher {
102
102
 
103
103
  // 如果上下文被销毁了, 就恢复上下文
104
104
  if (this.isRendererContextLost) {
105
- //@ts-ignore
106
- this.renderer['forceContextRestore']();
105
+ this.renderer.forceContextRestore();
107
106
  await new Promise(resolve => requestAnimationFrame(resolve));
108
107
  await new Promise(resolve => requestAnimationFrame(resolve));
109
108
  this.renderer.domElement.style.opacity = "1";
@@ -201,37 +200,25 @@ export default class ThreeBase extends EventDispatcher {
201
200
  let currentPosition = this.camera.position.clone();
202
201
  let currentCenter = this.controls.target.clone();
203
202
 
204
- if (position) {
205
- this.controlsPosition
206
- .setDuration(duration)
207
- .reset({
208
- x: currentPosition.x,
209
- y: currentPosition.y,
210
- z: currentPosition.z
211
- })
212
- .set({
213
- x: position.x,
214
- y: position.y,
215
- z: position.z
216
- });
217
- }
218
-
219
- if (center) {
220
- this.controlsCenter
221
- .setDuration(duration)
222
- .reset({
223
- x: currentCenter.x,
224
- y: currentCenter.y,
225
- z: currentCenter.z
226
- }).set({
227
- x: center.x,
228
- y: center.y,
229
- z: center.z
230
- });
231
- }
232
-
233
203
  // 等待动画执行完成
234
- await new Promise(resolve => setTimeout(resolve, Math.max(this.controlsCenter._duration, this.controlsPosition._duration)));
204
+ await Promise.all([
205
+ new Promise<void>(async (resolve, reject) => {
206
+ if (position) {
207
+ this.controlsPosition.setDuration(duration).reset({ x: currentPosition.x, y: currentPosition.y, z: currentPosition.z });
208
+ await this.controlsPosition.set({ x: position.x, y: position.y, z: position.z });
209
+ }
210
+ resolve();
211
+ }),
212
+ new Promise<void>(async (resolve, reject) => {
213
+ if (center) {
214
+ this.controlsCenter.setDuration(duration).reset({ x: currentCenter.x, y: currentCenter.y, z: currentCenter.z });
215
+ await this.controlsCenter.set({ x: center.x, y: center.y, z: center.z });
216
+ }
217
+ resolve();
218
+ }),
219
+
220
+ ]);
221
+
235
222
  }
236
223
 
237
224
  // 获取控制的位置和朝向 保留3位小数
@@ -255,7 +242,7 @@ export default class ThreeBase extends EventDispatcher {
255
242
  // 控制器类型
256
243
  controlType: "OrbitControls" | "MapControls" = "OrbitControls";
257
244
 
258
- // 记录一下空间平移方式
245
+ // 记录一下空间平移方式 在切换控制器的时候保留一下平移方式
259
246
  originScreenSpacePanning = false;
260
247
 
261
248
  //改变控制器的类型
@@ -283,7 +270,6 @@ export default class ThreeBase extends EventDispatcher {
283
270
  //是否需要渲染, 当autoRender=false的时候就需要 手动触发渲染
284
271
  needRender = false;
285
272
 
286
-
287
273
  // 停止渲染
288
274
  stopRender() {
289
275
  threeUtils.removeEventListener("requestAnimationFrame", this.renderBindThis);
@@ -340,6 +326,39 @@ export default class ThreeBase extends EventDispatcher {
340
326
  saveLink.click();
341
327
  }
342
328
 
329
+ private _preMesh = new Mesh();
330
+ private _preRT = new WebGLRenderTarget(128, 128, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
331
+
332
+ //预加载纹理图片
333
+ async preloadTexture(src: string) {
334
+ const texture = threeLoader.getTexture(src);
335
+ while (texture && !texture.image || !(texture.image as HTMLImageElement).complete) {
336
+ await new Promise(resolve => setTimeout(resolve, 50));
337
+ }
338
+
339
+ // 添加到计划任务中去
340
+ threeUtils.addWork(() => {
341
+ const originRenderTarget = this.renderer.getRenderTarget();
342
+ this.renderer.setRenderTarget(this._preRT);
343
+ (this._preMesh.material as MeshBasicMaterial).map = texture;
344
+ this.renderer.render(this._preMesh, this.camera);
345
+ this.renderer.setRenderTarget(originRenderTarget);
346
+ });
347
+ }
348
+
349
+ //预加载网格
350
+ async preloadGeometry(geometry: BufferGeometry) {
351
+
352
+ // 添加到计划任务中去
353
+ threeUtils.addWork(() => {
354
+ const originRenderTarget = this.renderer.getRenderTarget();
355
+ this.renderer.setRenderTarget(this._preRT);
356
+ this._preMesh.geometry = geometry;
357
+ this.renderer.render(this._preMesh, this.camera);
358
+ this.renderer.setRenderTarget(originRenderTarget);
359
+ });
360
+ }
361
+
343
362
  // 清理渲染目标
344
363
  clearRendererTargte(rendererTarget: WebGLRenderTarget | null) {
345
364
  const originTarget = this.renderer.getRenderTarget();
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { throttle } from "lodash";
9
- import { Event, EventDispatcher, Vector3 } from "three";
9
+ import { Event, EventDispatcher, EventListener, Vector3 } from "three";
10
10
  import { generateUUID } from "three/src/math/MathUtils";
11
11
 
12
12
 
@@ -107,7 +107,7 @@ class KeyContorls extends EventDispatcher {
107
107
  this._listeners = undefined;
108
108
  }, 1000, { trailing: false });
109
109
 
110
- addEventListener(type: string, listener: (event: Event) => void): void {
110
+ addEventListener<T extends string>(type: T, listener: EventListener<Event, T, this>): void {
111
111
  this.removeEvent(type);
112
112
  super.addEventListener(type, listener);
113
113
  }
@@ -10,11 +10,13 @@ import { Mesh } from "three";
10
10
  // 三维空间中的3D文字模型
11
11
  export default class Text3D extends Mesh {
12
12
 
13
- constructor(text: string = "Text2D") {
13
+ constructor(text: string = "Text3D") {
14
14
  super();
15
15
  }
16
16
 
17
-
17
+ // 字体的存储路径
18
+ static path: "http://drm.gitee.io/xsh-react-three-font/";
19
+
18
20
 
19
21
 
20
22
  }
@@ -2,7 +2,7 @@
2
2
  * @Author: xiaosihan
3
3
  * @Date: 2022-04-07 16:42:26
4
4
  * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2023-03-30 10:52:27
5
+ * @Last Modified time: 2023-02-07 11:11:48
6
6
  */
7
7
 
8
8
  import { DefaultLoadingManager, EventDispatcher, RepeatWrapping, Texture, TextureLoader, VideoTexture } from "three";
@@ -121,7 +121,7 @@ class ThreeLoader extends EventDispatcher {
121
121
 
122
122
  }();
123
123
  //@ts-ignore
124
- dracoLoader.setDecoderPath((process.env.NODE_ENV === "development") ? '/node_modules/three/examples/js/libs/draco/' : '');
124
+ dracoLoader.setDecoderPath((process.env.NODE_ENV === "development") ? '/node_modules/three/examples/jsm/libs/draco/' : '');
125
125
  loader.setDRACOLoader(dracoLoader);
126
126
  return loader;
127
127
  })()
package/lib/threeUtils.ts CHANGED
@@ -15,35 +15,40 @@ class ThreeUtils extends EventDispatcher {
15
15
  this.requestAnimationFrame();
16
16
  }
17
17
  //@ts-ignore
18
- isProd = process.env.NODE_ENV === "production";
18
+ isProd = (process.env.NODE_ENV === "production");
19
19
 
20
20
  //@ts-ignore
21
- isDev = process.env.NODE_ENV === "development";
21
+ isDev = (process.env.NODE_ENV === "development");
22
22
 
23
- timeTemp = performance.now();
23
+ _timeTemp = performance.now();
24
24
 
25
- accumulate = 0;// 事件分发次数
25
+ _accumulate = 0;// 事件分发次数
26
26
 
27
- box3 = new Box3();
28
- size = new Vector3();
29
- center = new Vector3();
27
+ _box3 = new Box3();
28
+ _size = new Vector3();
29
+ _center = new Vector3();
30
30
 
31
- clock = new Clock();
31
+ _clock = new Clock();
32
32
 
33
33
  requestAnimationFrame() {
34
- this.accumulate += 1;
35
- const timeTemp = this.timeTemp = performance.now();
34
+ this._accumulate += 1;
35
+ const timeTemp = this._timeTemp = performance.now();
36
+
36
37
  this.dispatchEvent({
37
38
  type: "requestAnimationFrame",
38
39
  timeTemp,
39
- accumulate: this.accumulate
40
+ accumulate: this._accumulate
40
41
  });
41
42
 
42
43
  this._computerDomZoom();
43
44
 
45
+ //执行一个计划任务
46
+ let work = this.workList.splice(0, 1)[0];
47
+ work && work();
48
+
44
49
  setTimeout(() => {
45
50
  this.requestAnimationFrame();
46
- }, 45 - this.clock.getDelta());
51
+ }, 45 - this._clock.getDelta());
47
52
  }
48
53
 
49
54
  // 需要保持宽高比的元素列表
@@ -89,6 +94,27 @@ class ThreeUtils extends EventDispatcher {
89
94
  }
90
95
  }
91
96
 
97
+ workList: Array<() => void> = [];
98
+
99
+ // 时钟对象
100
+ clock = new Clock();
101
+
102
+ // 按照任务队列依次执行计划任务 性能优化
103
+ /**
104
+ * @param {() => void} [callback]
105
+ * @param {boolean} [first=true] 需要优先执行
106
+ */
107
+ addWork(work?: () => void, first: boolean = false) {
108
+ // 加入任务队列
109
+ if (work && !this.workList.includes(work)) {
110
+ if (first) {
111
+ this.workList.splice(1, 0, work); // 优先执行的任务回调
112
+ } else {
113
+ this.workList.push(work);
114
+ }
115
+ }
116
+ }
117
+
92
118
  /**
93
119
  *判断一个元素是否在页面上
94
120
  */
@@ -107,56 +133,61 @@ class ThreeUtils extends EventDispatcher {
107
133
  // 获取中心点
108
134
  getCenter(object3d: Object3D | BufferGeometry) {
109
135
  if (object3d instanceof Object3D) {
110
- this.box3.setFromObject(object3d);
111
- this.box3.getCenter(this.center);
136
+ this._box3.setFromObject(object3d);
137
+ this._box3.getCenter(this._center);
112
138
  } else if (object3d instanceof BufferGeometry) {
113
139
  object3d.computeBoundingBox();
114
- object3d.boundingBox!.getCenter(this.center);
140
+ object3d.boundingBox!.getCenter(this._center);
115
141
  }
116
142
 
117
- return this.center;
143
+ return this._center;
118
144
  }
119
145
 
120
146
  // 获取模型大小
121
147
  getSize(object3d: Object3D | BufferGeometry) {
122
148
  if (object3d instanceof Object3D) {
123
- this.box3.setFromObject(object3d);
124
- this.box3.getSize(this.size);
149
+ this._box3.setFromObject(object3d);
150
+ this._box3.getSize(this._size);
125
151
  } else if (object3d instanceof BufferGeometry) {
126
152
  object3d.computeBoundingBox();
127
- object3d.boundingBox!.getSize(this.size);
153
+ object3d.boundingBox!.getSize(this._size);
128
154
  }
129
155
 
130
- return this.size;
156
+ return this._size;
131
157
  }
132
158
 
133
159
  // 模型对齐底面
134
160
  alignBottom(object3d: Object3D | BufferGeometry, y = 0) {
135
161
  if (object3d instanceof Object3D) {
136
- this.box3.setFromObject(object3d);
137
- this.box3.getCenter(this.center);
138
- this.box3.getSize(this.size);
139
- object3d.position.y -= (this.center.y - (this.size.y * 0.5));
162
+ this._box3.setFromObject(object3d);
163
+ this._box3.getCenter(this._center);
164
+ this._box3.getSize(this._size);
165
+ object3d.position.y -= (this._center.y - (this._size.y * 0.5));
140
166
  object3d.position.y += y;
141
167
  object3d.updateMatrixWorld(true);
142
168
  } else if (object3d instanceof BufferGeometry) {
143
169
  object3d.computeBoundingBox();
144
- object3d.translate(0, -object3d.boundingBox!.min.y, 0);
170
+ object3d.translate(0, -object3d.boundingBox!.min.y + y, 0);
145
171
  }
146
172
  }
147
173
 
148
174
  // 居中对象
149
175
  centerObject3D(object3d: Object3D | BufferGeometry) {
150
176
  if (object3d instanceof Object3D) {
151
- this.box3.setFromObject(object3d);
152
- this.box3.getCenter(this.center);
153
- object3d.position.sub(this.center);
177
+ this._box3.setFromObject(object3d);
178
+ this._box3.getCenter(this._center);
179
+ object3d.position.sub(this._center);
154
180
  object3d.updateMatrixWorld(true);
155
181
  } else if (object3d instanceof BufferGeometry) {
156
182
  object3d.center();
157
183
  }
158
184
  }
159
185
 
186
+ //居中对象
187
+ center(object3d: Object3D | BufferGeometry) {
188
+ this.centerObject3D(object3d);
189
+ }
190
+
160
191
  //缩放至指定大小
161
192
  scaleTo(object3d: Object3D | BufferGeometry, size: number = 1) {
162
193
  const originSize = this.getSize(object3d);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "three-base",
3
- "version": "1.0.57",
3
+ "version": "1.0.59",
4
4
  "description": "three 3d three-base",
5
5
  "repository": {
6
6
  "type": "git",
@@ -41,10 +41,10 @@
41
41
  "apng-js": "^1",
42
42
  "element-resize-event": "^3",
43
43
  "lodash": "^4",
44
- "three": "0.129.0",
44
+ "three": ">=0.150.0",
45
45
  "vite": "^4",
46
46
  "three-spritetext": "^1",
47
- "@types/three": "0.129.0",
47
+ "@types/three": ">=0.149.0",
48
48
  "@types/element-resize-event": "^3",
49
49
  "@types/lodash": "^4",
50
50
  "@types/node": "^18"