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.
- package/lib/KeyFrameAnimation.ts +2 -2
- package/lib/ThreeBase.ts +55 -36
- package/lib/keyContorls.ts +2 -2
- package/lib/text/Text3D.ts +4 -2
- package/lib/threeLoader.ts +2 -2
- package/lib/threeUtils.ts +59 -28
- package/package.json +3 -3
package/lib/KeyFrameAnimation.ts
CHANGED
|
@@ -90,9 +90,9 @@ export default class KeyframeAnimation extends Object3D {
|
|
|
90
90
|
|
|
91
91
|
// 更具关键帧的信息更新 对象的位置
|
|
92
92
|
update() {
|
|
93
|
-
const {
|
|
93
|
+
const { _timeTemp } = threeUtils;
|
|
94
94
|
const maxtimetemp = last(this.keyframes)!.timeTemp;
|
|
95
|
-
const currentTime =
|
|
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-
|
|
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
|
-
|
|
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
|
|
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();
|
package/lib/keyContorls.ts
CHANGED
|
@@ -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:
|
|
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
|
}
|
package/lib/text/Text3D.ts
CHANGED
|
@@ -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 = "
|
|
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
|
}
|
package/lib/threeLoader.ts
CHANGED
|
@@ -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-
|
|
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/
|
|
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
|
-
|
|
23
|
+
_timeTemp = performance.now();
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
_accumulate = 0;// 事件分发次数
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
_box3 = new Box3();
|
|
28
|
+
_size = new Vector3();
|
|
29
|
+
_center = new Vector3();
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
_clock = new Clock();
|
|
32
32
|
|
|
33
33
|
requestAnimationFrame() {
|
|
34
|
-
this.
|
|
35
|
-
const timeTemp = this.
|
|
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.
|
|
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.
|
|
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.
|
|
111
|
-
this.
|
|
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.
|
|
140
|
+
object3d.boundingBox!.getCenter(this._center);
|
|
115
141
|
}
|
|
116
142
|
|
|
117
|
-
return this.
|
|
143
|
+
return this._center;
|
|
118
144
|
}
|
|
119
145
|
|
|
120
146
|
// 获取模型大小
|
|
121
147
|
getSize(object3d: Object3D | BufferGeometry) {
|
|
122
148
|
if (object3d instanceof Object3D) {
|
|
123
|
-
this.
|
|
124
|
-
this.
|
|
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.
|
|
153
|
+
object3d.boundingBox!.getSize(this._size);
|
|
128
154
|
}
|
|
129
155
|
|
|
130
|
-
return this.
|
|
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.
|
|
137
|
-
this.
|
|
138
|
-
this.
|
|
139
|
-
object3d.position.y -= (this.
|
|
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.
|
|
152
|
-
this.
|
|
153
|
-
object3d.position.sub(this.
|
|
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.
|
|
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.
|
|
44
|
+
"three": ">=0.150.0",
|
|
45
45
|
"vite": "^4",
|
|
46
46
|
"three-spritetext": "^1",
|
|
47
|
-
"@types/three": "0.
|
|
47
|
+
"@types/three": ">=0.149.0",
|
|
48
48
|
"@types/element-resize-event": "^3",
|
|
49
49
|
"@types/lodash": "^4",
|
|
50
50
|
"@types/node": "^18"
|