three-base 1.0.58 → 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 +54 -34
- package/lib/text/Text3D.ts +4 -2
- package/lib/threeUtils.ts +59 -28
- package/package.json +1 -1
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
|
@@ -7,7 +7,7 @@
|
|
|
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";
|
|
@@ -200,37 +200,25 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
200
200
|
let currentPosition = this.camera.position.clone();
|
|
201
201
|
let currentCenter = this.controls.target.clone();
|
|
202
202
|
|
|
203
|
-
if (position) {
|
|
204
|
-
this.controlsPosition
|
|
205
|
-
.setDuration(duration)
|
|
206
|
-
.reset({
|
|
207
|
-
x: currentPosition.x,
|
|
208
|
-
y: currentPosition.y,
|
|
209
|
-
z: currentPosition.z
|
|
210
|
-
})
|
|
211
|
-
.set({
|
|
212
|
-
x: position.x,
|
|
213
|
-
y: position.y,
|
|
214
|
-
z: position.z
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (center) {
|
|
219
|
-
this.controlsCenter
|
|
220
|
-
.setDuration(duration)
|
|
221
|
-
.reset({
|
|
222
|
-
x: currentCenter.x,
|
|
223
|
-
y: currentCenter.y,
|
|
224
|
-
z: currentCenter.z
|
|
225
|
-
}).set({
|
|
226
|
-
x: center.x,
|
|
227
|
-
y: center.y,
|
|
228
|
-
z: center.z
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
|
|
232
203
|
// 等待动画执行完成
|
|
233
|
-
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
|
+
|
|
234
222
|
}
|
|
235
223
|
|
|
236
224
|
// 获取控制的位置和朝向 保留3位小数
|
|
@@ -254,7 +242,7 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
254
242
|
// 控制器类型
|
|
255
243
|
controlType: "OrbitControls" | "MapControls" = "OrbitControls";
|
|
256
244
|
|
|
257
|
-
// 记录一下空间平移方式
|
|
245
|
+
// 记录一下空间平移方式 在切换控制器的时候保留一下平移方式
|
|
258
246
|
originScreenSpacePanning = false;
|
|
259
247
|
|
|
260
248
|
//改变控制器的类型
|
|
@@ -282,9 +270,8 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
282
270
|
//是否需要渲染, 当autoRender=false的时候就需要 手动触发渲染
|
|
283
271
|
needRender = false;
|
|
284
272
|
|
|
285
|
-
|
|
286
273
|
// 停止渲染
|
|
287
|
-
stopRender(){
|
|
274
|
+
stopRender() {
|
|
288
275
|
threeUtils.removeEventListener("requestAnimationFrame", this.renderBindThis);
|
|
289
276
|
this.renderer.forceContextLoss();
|
|
290
277
|
// 标记上下文被销毁了
|
|
@@ -339,6 +326,39 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
339
326
|
saveLink.click();
|
|
340
327
|
}
|
|
341
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
|
+
|
|
342
362
|
// 清理渲染目标
|
|
343
363
|
clearRendererTargte(rendererTarget: WebGLRenderTarget | null) {
|
|
344
364
|
const originTarget = this.renderer.getRenderTarget();
|
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/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);
|