@ridp/threejs 0.0.1

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 (46) hide show
  1. package/dist/common-DGdtPI9P.js +28 -0
  2. package/dist/common-DbWzzhhR.cjs +1 -0
  3. package/dist/disposeObject-BuI3II7v.cjs +1 -0
  4. package/dist/disposeObject-CmFSSgi7.js +616 -0
  5. package/dist/draco/README.md +32 -0
  6. package/dist/draco/draco_decoder.js +34 -0
  7. package/dist/draco/draco_decoder.wasm +0 -0
  8. package/dist/draco/draco_encoder.js +33 -0
  9. package/dist/draco/draco_wasm_wrapper.js +117 -0
  10. package/dist/draco/gltf/draco_decoder.js +33 -0
  11. package/dist/draco/gltf/draco_decoder.wasm +0 -0
  12. package/dist/draco/gltf/draco_encoder.js +33 -0
  13. package/dist/draco/gltf/draco_wasm_wrapper.js +116 -0
  14. package/dist/hdr/slightly_overcast_sky_dome_1k.hdr +0 -0
  15. package/dist/hooks.cjs +1 -0
  16. package/dist/hooks.js +11 -0
  17. package/dist/threejs.cjs +1 -0
  18. package/dist/threejs.js +24 -0
  19. package/dist/useGLTFLoader-CkQCsokF.cjs +6 -0
  20. package/dist/useGLTFLoader-CoqckCZO.js +2641 -0
  21. package/dist/utils.cjs +1 -0
  22. package/dist/utils.js +15 -0
  23. package/package.json +26 -0
  24. package/src/assets/draco/README.md +32 -0
  25. package/src/assets/draco/draco_decoder.js +34 -0
  26. package/src/assets/draco/draco_decoder.wasm +0 -0
  27. package/src/assets/draco/draco_encoder.js +33 -0
  28. package/src/assets/draco/draco_wasm_wrapper.js +117 -0
  29. package/src/assets/draco/gltf/draco_decoder.js +33 -0
  30. package/src/assets/draco/gltf/draco_decoder.wasm +0 -0
  31. package/src/assets/draco/gltf/draco_encoder.js +33 -0
  32. package/src/assets/draco/gltf/draco_wasm_wrapper.js +116 -0
  33. package/src/assets/hdr/slightly_overcast_sky_dome_1k.hdr +0 -0
  34. package/src/hooks/index.js +5 -0
  35. package/src/hooks/useGLTFLoader.js +24 -0
  36. package/src/hooks/useLight.js +25 -0
  37. package/src/hooks/useObb.js +74 -0
  38. package/src/hooks/useRaycaster.js +78 -0
  39. package/src/hooks/useThreeJs.js +280 -0
  40. package/src/index.js +2 -0
  41. package/src/utils/common.js +27 -0
  42. package/src/utils/css3dHelper.js +24 -0
  43. package/src/utils/disposeObject.js +39 -0
  44. package/src/utils/helper.js +56 -0
  45. package/src/utils/index.js +4 -0
  46. package/vite.config.js +35 -0
@@ -0,0 +1,280 @@
1
+ import {
2
+ Scene,
3
+ Group,
4
+ PerspectiveCamera,
5
+ WebGLRenderer,
6
+ Color,
7
+ Box3,
8
+ Vector3,
9
+ MathUtils,
10
+ EquirectangularReflectionMapping,
11
+ } from "three";
12
+ import Stats from "three/addons/libs/stats.module.js";
13
+ import { CSS3DRenderer } from "three/examples/jsm/renderers/CSS3DRenderer.js";
14
+ import { RGBELoader } from "three/examples/jsm/Addons.js";
15
+
16
+ import {
17
+ createOrbitControl,
18
+ createAxesHelper,
19
+ createGridHelper,
20
+ disposeThreeObject,
21
+ } from "../utils";
22
+
23
+ // const hdrImage = new URL(
24
+ // "./assets/hdr/slightly_overcast_sky_dome_1k.hdr",
25
+ // import.meta.url
26
+ // ).href;
27
+
28
+ // import hdrImage from "../../public/hdr/slightly_overcast_sky_dome_1k.hdr";
29
+ // const hdrImage = '/hdr/slightly_overcast_sky_dome_1k.hdr'
30
+
31
+ const rgbeLoader = new RGBELoader();
32
+ // 缓存Hdr
33
+ const cacheHdr = {};
34
+ // 默认控制器配置
35
+ const defaultControlOpt = {
36
+ enableDamping: true,
37
+ dampingFactor: 0.25,
38
+ screenSpacePanning: false,
39
+ minDistance: 0.1,
40
+ maxDistance: 1000,
41
+ maxPolarAngle: Math.PI / 2,
42
+ };
43
+
44
+ const renderer = new WebGLRenderer({
45
+ antialias: true,
46
+ alpha: true,
47
+ precision: "mediump",
48
+ });
49
+ export function useThreeJs(selector, option) {
50
+ const _option = Object.assign(
51
+ {
52
+ css3d: false,
53
+ stats: false,
54
+ axesHelper: {
55
+ init: false,
56
+ size: 10,
57
+ },
58
+ gridHelper: {
59
+ init: false,
60
+ },
61
+ control: {
62
+ init: true,
63
+ options: {},
64
+ },
65
+ envImage: true,
66
+ },
67
+ option || {}
68
+ );
69
+
70
+ let el,
71
+ stats,
72
+ css3dRenderer,
73
+ control,
74
+ animateCbs = [];
75
+
76
+ const domWidth = ref(0);
77
+ const domHeight = ref(0);
78
+
79
+ const scene = new Scene({});
80
+ scene.background = new Color("#222b38");
81
+ const objectGroup = new Group();
82
+ scene.add(objectGroup);
83
+
84
+ renderer.setPixelRatio(window.devicePixelRatio);
85
+ const camera = new PerspectiveCamera(50, 1, 0.1, 2000);
86
+ const tanFOV = Math.tan(((Math.PI / 180) * camera.fov) / 2);
87
+
88
+ function init() {
89
+ const size = getTargetSize();
90
+ domWidth.value = size[0];
91
+ domHeight.value = size[1];
92
+
93
+ camera.aspect = domWidth.value / domHeight.value;
94
+ camera.position.set(47, 39, 100);
95
+ camera.fov =
96
+ (360 / Math.PI) * Math.atan(tanFOV * (domHeight.value / domWidth.value));
97
+ camera.updateProjectionMatrix();
98
+
99
+ renderer.setSize(domWidth.value, domHeight.value);
100
+ el.appendChild(renderer.domElement);
101
+
102
+ // 环境贴图
103
+ _option.envImage && initEnvImage(scene);
104
+
105
+ _option.stats && initStats();
106
+ // css3d
107
+ _option.css3d && createCss3dRenderer();
108
+ // axesHelper
109
+ if (_option.axesHelper && _option.axesHelper.init) {
110
+ const axesHelper = createAxesHelper(_option.axesHelper.size || 10);
111
+ scene.add(axesHelper);
112
+ }
113
+ // GridHelper
114
+ if (_option.gridHelper && _option.gridHelper.init) {
115
+ const gridHelper = createGridHelper(
116
+ _option.gridHelper.size || 150,
117
+ _option.gridHelper.options || {}
118
+ );
119
+ scene.add(gridHelper);
120
+ }
121
+ // 控制器
122
+ if (_option.control && _option.control.init) {
123
+ control = createOrbitControl(camera, renderer.domElement);
124
+ const controlOpt = _option.control.options || defaultControlOpt;
125
+ Object.keys(controlOpt).forEach((key) => {
126
+ control[key] = controlOpt[key];
127
+ });
128
+ }
129
+
130
+ return { control, scene, camera, renderer };
131
+ }
132
+
133
+ function addAnimate(animate) {
134
+ animateCbs.push(animate);
135
+ }
136
+
137
+ function animate(cbs) {
138
+ animateCbs &&
139
+ animateCbs.length &&
140
+ animateCbs.forEach((fun) => {
141
+ typeof fun === "function" && fun();
142
+ });
143
+
144
+ control && control.update();
145
+ renderer.render(scene, camera);
146
+ stats && stats.update();
147
+ css3dRenderer && css3dRenderer.render(scene, camera);
148
+
149
+ requestAnimationFrame(animate);
150
+ }
151
+
152
+ function onResize() {
153
+ nextTick(() => {
154
+ const size = getTargetSize();
155
+ domWidth.value = size[0];
156
+ domHeight.value = size[1];
157
+ camera.aspect = domWidth.value / domHeight.value;
158
+ // adjust the FOV
159
+ camera.fov =
160
+ (360 / Math.PI) *
161
+ Math.atan(tanFOV * (domHeight.value / domWidth.value));
162
+ camera.updateProjectionMatrix();
163
+ camera.lookAt(scene.position);
164
+
165
+ renderer.render(scene, camera);
166
+ renderer.setSize(domWidth.value, domHeight.value);
167
+
168
+ css3dRenderer && css3dRenderer.setSize(domWidth.value, domHeight.value);
169
+ });
170
+ }
171
+
172
+ function getTargetSize() {
173
+ el = document.querySelector(selector);
174
+ return [el.clientWidth, el.clientHeight];
175
+ }
176
+
177
+ function initStats() {
178
+ stats = new Stats();
179
+ stats.dom.style.cssText =
180
+ "position:absolute;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000";
181
+ el.appendChild(stats.dom);
182
+ }
183
+
184
+ /**物体视窗自动适应
185
+ *
186
+ * @param {*} model
187
+ * @param {*} scale
188
+ * @param {*} camera
189
+ * @param {*} controls
190
+ */
191
+ function frameArea(model, scale, camera, controls) {
192
+ const box = new Box3().setFromObject(model);
193
+ const boxSize = box.getSize(new Vector3()).length();
194
+ const boxCenter = box.getCenter(new Vector3());
195
+
196
+ const sizeToFitOnScreen = boxSize * scale;
197
+ const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
198
+ const halfFovY = MathUtils.degToRad(camera.fov * 0.5);
199
+ const distance = halfSizeToFitOnScreen / Math.tan(halfFovY);
200
+ const direction = new Vector3()
201
+ .subVectors(camera.position, boxCenter)
202
+ .multiply(new Vector3(1, 1, 1))
203
+ .normalize();
204
+
205
+ const neP = direction.multiplyScalar(distance).add(boxCenter);
206
+
207
+ const targetOption = {
208
+ x: neP.x,
209
+ y: neP.y,
210
+ z: neP.z,
211
+ lookAt_x: boxCenter.x,
212
+ lookAt_y: boxCenter.y,
213
+ lookAt_z: boxCenter.z,
214
+ };
215
+
216
+ camera.position.set(targetOption.x, targetOption.y, targetOption.z);
217
+ camera.lookAt(
218
+ targetOption.lookAt_x,
219
+ targetOption.lookAt_y,
220
+ targetOption.lookAt_z
221
+ );
222
+ camera.updateProjectionMatrix();
223
+ controls.target.copy(boxCenter);
224
+ controls.update();
225
+ return boxSize;
226
+ }
227
+
228
+ function createCss3dRenderer() {
229
+ css3dRenderer = new CSS3DRenderer();
230
+ css3dRenderer.setSize(domWidth.value, domHeight.value);
231
+ css3dRenderer.domElement.style.position = "absolute";
232
+ css3dRenderer.domElement.style.top = 0;
233
+ css3dRenderer.domElement.style.left = 0;
234
+ css3dRenderer.domElement.style.pointerEvents = "none";
235
+ el.appendChild(css3dRenderer.domElement);
236
+ }
237
+
238
+ function dispose() {
239
+ disposeThreeObject(scene);
240
+ }
241
+
242
+ return {
243
+ init,
244
+ dispose,
245
+ animate,
246
+ onResize,
247
+ addAnimate,
248
+ frameArea,
249
+
250
+ objectGroup,
251
+ scene,
252
+ camera,
253
+ control,
254
+ renderer,
255
+ domWidth,
256
+ domHeight,
257
+ };
258
+ }
259
+
260
+ // 加载环境贴图
261
+ export async function initEnvImage(scene, hdrImg) {
262
+ if (!hdrImg) return;
263
+ if (cacheHdr[hdrImg]) {
264
+ const texture = cacheHdr[hdrImg];
265
+ scene.environment = texture;
266
+ return;
267
+ }
268
+
269
+ return new Promise((resolve, reject) => {
270
+ rgbeLoader.load(hdrImg, resolve, undefined, reject);
271
+ })
272
+ .then((texture) => {
273
+ texture.mapping = EquirectangularReflectionMapping;
274
+ scene.environment = texture;
275
+ cacheHdr[hdrImg] = texture;
276
+ })
277
+ .catch((e) => {
278
+ console.log(" =====> e:", e);
279
+ });
280
+ }
package/src/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./hooks";
2
+ export * from "./utils";
@@ -0,0 +1,27 @@
1
+ export const getCommonParent = (meshList, objectGroup) => {
2
+ const parentCount = {};
3
+
4
+ meshList.forEach((mesh) => {
5
+ let parent = mesh.parent;
6
+ while (parent) {
7
+ if (parentCount[parent.uuid]) {
8
+ parentCount[parent.uuid]++;
9
+ } else {
10
+ parentCount[parent.uuid] = 1;
11
+ }
12
+ parent = parent.parent;
13
+ }
14
+ });
15
+
16
+ let commonParent = null;
17
+ let maxCount = 0;
18
+
19
+ for (const uuid in parentCount) {
20
+ if (parentCount[uuid] > maxCount) {
21
+ maxCount = parentCount[uuid];
22
+ commonParent = objectGroup.getObjectByProperty("uuid", uuid);
23
+ }
24
+ }
25
+
26
+ return commonParent;
27
+ };
@@ -0,0 +1,24 @@
1
+ import { CSS3DSprite } from "three/examples/jsm/Addons.js";
2
+
3
+ /**
4
+ * 创建 CSS3DSprite 信息面板
5
+ * @param { string } id 元素ID
6
+ * @param { [ number, number, number ]} scale 缩放
7
+ * @returns new CSS3DSprite()
8
+ *
9
+ * 注意: html元素不能设置模板为结对定位!!!
10
+ */
11
+ export function createInfoPlane(id, scale = [0.3, 0.3, 0.3]) {
12
+ const el = document.querySelector(`#${id}`);
13
+ if (!el) {
14
+ console.log(" 获取 infoPlane 元素失败 (id) =====> :", id);
15
+ return;
16
+ }
17
+ const _el = el.cloneNode(true);
18
+ _el.style.display = "block";
19
+
20
+ const plane = new CSS3DSprite(_el);
21
+ plane.visible = false;
22
+ plane.scale.set(...scale);
23
+ return plane;
24
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * 递归释放THREE.js对象 / 材质
3
+ * @param { Object3D } object
4
+ */
5
+ export const disposeThreeObject = (object) => {
6
+ if (object.geometry) {
7
+ object.geometry.dispose();
8
+ }
9
+
10
+ if (object.material) {
11
+ // 如果材质是一个数组(例如多材质对象),需要遍历数组并释放每个材质
12
+ if (Array.isArray(object.material)) {
13
+ object.material.forEach((material) => {
14
+ disposeMaterial(material);
15
+ });
16
+ } else {
17
+ disposeMaterial(object.material);
18
+ }
19
+ }
20
+
21
+ // 递归释放子对象
22
+ if (object.children) {
23
+ object.children.forEach((child) => disposeThreeObject(child));
24
+ }
25
+ };
26
+
27
+ /**
28
+ * 释放THREE.js材质
29
+ * @param { Material } material
30
+ */
31
+ function disposeMaterial(material) {
32
+ // 释放材质的纹理
33
+ for (const key in material) {
34
+ if (material[key] && material[key].isTexture) {
35
+ material[key].dispose();
36
+ }
37
+ }
38
+ material.dispose();
39
+ }
@@ -0,0 +1,56 @@
1
+ import {
2
+ BoxHelper,
3
+ GridHelper,
4
+ Raycaster,
5
+ Vector2,
6
+ AxesHelper,
7
+ Vector3,
8
+ ArrowHelper,
9
+ CameraHelper
10
+ } from "three";
11
+ import { OrbitControls } from "three/addons/controls/OrbitControls.js";
12
+ import { MapControls } from "three/addons/controls/MapControls.js";
13
+
14
+
15
+ export function createCameraHelper(camera){
16
+ return new CameraHelper(camera);
17
+ }
18
+
19
+ export function createGridHelper(size = 150, ...args) {
20
+ return new GridHelper(size, size / 10, ...args);
21
+ }
22
+
23
+ export function createBox3Helper(model) {
24
+ return new BoxHelper(model, 0xffff00);
25
+ }
26
+
27
+ export function createOrbitControl(camera, dom) {
28
+ return new OrbitControls(camera, dom);
29
+ }
30
+
31
+ export function createMapControls(camera, dom) {
32
+ return new MapControls(camera, dom);
33
+ }
34
+
35
+ export function createRaycaster() {
36
+ const raycaster = new Raycaster();
37
+ const pointer = new Vector2(0, 0);
38
+ return {
39
+ raycaster,
40
+ pointer,
41
+ };
42
+ }
43
+
44
+ export function createAxesHelper(size = 10) {
45
+ return new AxesHelper(size);
46
+ }
47
+
48
+ export function createArrowHelper(
49
+ dir = new Vector3(1, 1, 1),
50
+ ori = new Vector3(10, 10, 10),
51
+ length = 5,
52
+ hex = 0xffff00
53
+ ) {
54
+ dir.normalize();
55
+ return new ArrowHelper(dir, ori, length, hex);
56
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./helper.js";
2
+ export * from "./css3dHelper.js";
3
+ export * from "./disposeObject.js";
4
+ export * from "./common.js";
package/vite.config.js ADDED
@@ -0,0 +1,35 @@
1
+ import { dirname, resolve } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { defineConfig } from "vite";
4
+
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+
7
+ export default defineConfig({
8
+ resolve: {
9
+ alias: {
10
+ "@": resolve(__dirname, "src"),
11
+ },
12
+ },
13
+ build: {
14
+ lib: {
15
+ entry: {
16
+ threejs: resolve(__dirname, "src/index.js"),
17
+ hooks: resolve(__dirname, "src/hooks/index.js"),
18
+ utils: resolve(__dirname, "src/utils/index.js"),
19
+ },
20
+ name: "threejs",
21
+ },
22
+ rollupOptions: {
23
+ // 确保外部化处理那些
24
+ // 你不想打包进库的依赖
25
+ external: ["three"],
26
+ output: {
27
+ // 在 UMD 构建模式下为这些外部化的依赖
28
+ // 提供一个全局变量
29
+ globals: {
30
+ three: "three",
31
+ },
32
+ },
33
+ },
34
+ },
35
+ });