@preference-sl/pref-viewer 2.11.0-beta.9 → 2.11.0
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/package.json +61 -50
- package/src/babylonjs-animation-controller.js +58 -76
- package/src/babylonjs-animation-opening-menu.js +189 -154
- package/src/babylonjs-animation-opening.js +67 -36
- package/src/babylonjs-controller.js +189 -60
- package/src/file-storage.js +11 -2
- package/src/index.js +18 -912
- package/src/panzoom-controller.js +92 -55
- package/src/pref-viewer-2d.js +15 -3
- package/src/pref-viewer-3d-data.js +3 -2
- package/src/pref-viewer-3d.js +11 -4
- package/src/pref-viewer-dialog.js +16 -9
- package/src/pref-viewer-task.js +1 -1
- package/src/pref-viewer.js +934 -0
- package/src/styles.js +334 -0
- package/src/svg-resolver.js +23 -0
- package/src/css/pref-viewer-2d.css +0 -39
- package/src/css/pref-viewer-3d.css +0 -28
- package/src/css/pref-viewer-dialog.css +0 -105
- package/src/css/pref-viewer.css +0 -11
package/package.json
CHANGED
|
@@ -1,53 +1,64 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
2
|
+
"name": "@preference-sl/pref-viewer",
|
|
3
|
+
"version": "2.11.0",
|
|
4
|
+
"description": "Web Component to preview GLTF models with Babylon.js",
|
|
5
|
+
"author": "Alex Moreno Palacio <amoreno@preference.es>",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build:prefweb": "webpack --config webpack.config.cjs --mode production",
|
|
8
|
+
"build:prefweb:dev": "webpack --config webpack.config.cjs --mode development",
|
|
9
|
+
"release": "standard-version --releaseCommitMessageFormat \"chore(release): {{currentTag}} [skip ci]\"",
|
|
10
|
+
"release:beta": "standard-version --prerelease beta --releaseCommitMessageFormat \"chore(release): {{currentTag}} [skip ci]\"",
|
|
11
|
+
"build": "esbuild src/index.js --bundle --platform=node --format=esm --outfile=dist/bundle.js --sourcemap",
|
|
12
|
+
"start": "npm run build && http-server -c-1 . -p 8080",
|
|
13
|
+
"test": "vitest"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://bitbucket.org/preferencesl/pref-viewer.git"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"type": "module",
|
|
24
|
+
"main": "src/index.js",
|
|
25
|
+
"types": "index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"import": "./src/index.js",
|
|
29
|
+
"require": "./src/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"sideEffects": false,
|
|
33
|
+
"files": [
|
|
34
|
+
"src",
|
|
35
|
+
"index.d.ts"
|
|
36
|
+
],
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@babylonjs/core": "^8.39.2",
|
|
39
|
+
"@babylonjs/loaders": "^8.39.2",
|
|
40
|
+
"@babylonjs/serializers": "^8.39.2",
|
|
41
|
+
"@panzoom/panzoom": "^4.6.0",
|
|
42
|
+
"babylonjs-gltf2interface": "^8.39.2",
|
|
43
|
+
"buffer": "^6.0.3",
|
|
44
|
+
"idb": "^8.0.3",
|
|
45
|
+
"is-svg": "^6.1.0",
|
|
46
|
+
"jszip": "^3.10.1",
|
|
47
|
+
"stream": "^0.0.3",
|
|
48
|
+
"string_decoder": "^1.3.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@babel/core": "^7.22.0",
|
|
52
|
+
"@babel/preset-env": "^7.22.0",
|
|
53
|
+
"babel-loader": "^9.2.1",
|
|
54
|
+
"clean-webpack-plugin": "^4.0.0",
|
|
55
|
+
"esbuild": "^0.25.10",
|
|
56
|
+
"http-server": "^14.1.1",
|
|
57
|
+
"jsdom": "^26.1.0",
|
|
58
|
+
"standard-version": "^9.5.0",
|
|
59
|
+
"terser-webpack-plugin": "^5.3.6",
|
|
60
|
+
"vitest": "^3.2.3",
|
|
61
|
+
"webpack": "^5.88.2",
|
|
62
|
+
"webpack-cli": "^5.1.4"
|
|
28
63
|
}
|
|
29
|
-
},
|
|
30
|
-
"sideEffects": false,
|
|
31
|
-
"files": [
|
|
32
|
-
"src",
|
|
33
|
-
"index.d.ts"
|
|
34
|
-
],
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"@babylonjs/core": "^8.36.1",
|
|
37
|
-
"@babylonjs/gui": "^8.36.1",
|
|
38
|
-
"@babylonjs/loaders": "^8.36.1",
|
|
39
|
-
"@babylonjs/serializers": "^8.36.1",
|
|
40
|
-
"@panzoom/panzoom": "^4.6.0",
|
|
41
|
-
"babylonjs-gltf2interface": "^8.36.1",
|
|
42
|
-
"idb": "^8.0.3",
|
|
43
|
-
"is-svg": "^6.1.0",
|
|
44
|
-
"jszip": "^3.10.1"
|
|
45
|
-
},
|
|
46
|
-
"devDependencies": {
|
|
47
|
-
"esbuild": "^0.25.10",
|
|
48
|
-
"http-server": "^14.1.1",
|
|
49
|
-
"jsdom": "^26.1.0",
|
|
50
|
-
"standard-version": "^9.5.0",
|
|
51
|
-
"vitest": "^3.2.3"
|
|
52
|
-
}
|
|
53
64
|
}
|
|
@@ -1,28 +1,35 @@
|
|
|
1
|
-
import { Color3, HighlightLayer, Mesh, PickingInfo,
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
import { Color3, HighlightLayer, Mesh, PickingInfo, Scene } from "@babylonjs/core";
|
|
2
|
+
import { PrefViewerColors } from "./styles.js";
|
|
3
|
+
import OpeningAnimation from "./babylonjs-animation-opening.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* BabylonJSAnimationController - Manages animation playback and interactive
|
|
6
|
+
* BabylonJSAnimationController - Manages animation playback, highlighting, and interactive controls for animated nodes in Babylon.js scenes.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* Summary:
|
|
9
|
+
* This class detects, groups, and manages opening/closing animations for scene nodes, provides interactive highlighting of animated nodes and their meshes, and displays a menu for animation control. It is designed for integration with product configurators and interactive 3D applications using Babylon.js.
|
|
10
|
+
*
|
|
11
|
+
* Key features:
|
|
9
12
|
* - Detects and groups opening/closing animations in the scene.
|
|
10
13
|
* - Tracks animated transformation nodes and their relationships to meshes.
|
|
11
|
-
* - Highlights animated nodes and their child meshes
|
|
12
|
-
* - Displays and disposes the animation control menu
|
|
13
|
-
* - Provides API for
|
|
14
|
+
* - Highlights animated nodes and their child meshes on pointer hover.
|
|
15
|
+
* - Displays and disposes the animation control menu for animated nodes.
|
|
16
|
+
* - Provides public API for highlighting, showing the animation menu, and disposing resources.
|
|
17
|
+
* - Cleans up all resources and observers to prevent memory leaks.
|
|
14
18
|
*
|
|
15
19
|
* Public Methods:
|
|
16
20
|
* - dispose(): Disposes all resources managed by the animation controller.
|
|
21
|
+
* - hightlightMeshes(pickingInfo): Highlights meshes that are children of an animated node when hovered.
|
|
22
|
+
* - hideMenu(): Hides and disposes the animation control menu if it exists.
|
|
23
|
+
* - showMenu(pickingInfo): Displays the animation control menu for the animated node under the pointer.
|
|
17
24
|
*
|
|
18
25
|
* @class
|
|
19
26
|
*/
|
|
20
27
|
export default class BabylonJSAnimationController {
|
|
21
28
|
#scene = null;
|
|
29
|
+
#canvas = null;
|
|
22
30
|
#animatedNodes = [];
|
|
23
31
|
#highlightLayer = null;
|
|
24
|
-
#highlightColor =
|
|
25
|
-
#advancedDynamicTexture = null;
|
|
32
|
+
#highlightColor = Color3.FromHexString(PrefViewerColors.primary);
|
|
26
33
|
#openingAnimations = [];
|
|
27
34
|
|
|
28
35
|
/**
|
|
@@ -31,8 +38,8 @@ export default class BabylonJSAnimationController {
|
|
|
31
38
|
*/
|
|
32
39
|
constructor(scene) {
|
|
33
40
|
this.#scene = scene;
|
|
41
|
+
this.#canvas = this.#scene._engine._renderingCanvas;
|
|
34
42
|
this.#initializeAnimations();
|
|
35
|
-
this.#setupPointerObservers();
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
/**
|
|
@@ -40,11 +47,12 @@ export default class BabylonJSAnimationController {
|
|
|
40
47
|
* @private
|
|
41
48
|
*/
|
|
42
49
|
#initializeAnimations() {
|
|
50
|
+
this.hideMenu(); // Clean up any existing menus
|
|
43
51
|
if (!this.#scene.animationGroups.length) {
|
|
44
52
|
return;
|
|
45
53
|
}
|
|
46
54
|
this.#getAnimatedNodes();
|
|
47
|
-
this.#
|
|
55
|
+
this.#getOpeningAnimations();
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
/**
|
|
@@ -71,7 +79,7 @@ export default class BabylonJSAnimationController {
|
|
|
71
79
|
* @description
|
|
72
80
|
* Uses animation group names with the pattern "animation_open_<name>" and "animation_close_<name>".
|
|
73
81
|
*/
|
|
74
|
-
#
|
|
82
|
+
#getOpeningAnimations() {
|
|
75
83
|
const openings = {};
|
|
76
84
|
this.#scene.animationGroups.forEach((animationGroup) => {
|
|
77
85
|
const match = animationGroup.name.match(/^animation_(open|close)_(.+)$/);
|
|
@@ -122,12 +130,36 @@ export default class BabylonJSAnimationController {
|
|
|
122
130
|
return nodeId;
|
|
123
131
|
};
|
|
124
132
|
|
|
133
|
+
/**
|
|
134
|
+
* ---------------------------
|
|
135
|
+
* Public methods
|
|
136
|
+
* ---------------------------
|
|
137
|
+
*/
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Disposes all resources managed by the animation controller.
|
|
141
|
+
* Cleans up the highlight layer, animation menu, and internal animation/node lists.
|
|
142
|
+
* Should be called when the controller is no longer needed to prevent memory leaks.
|
|
143
|
+
* @public
|
|
144
|
+
*/
|
|
145
|
+
dispose() {
|
|
146
|
+
if (this.#highlightLayer) {
|
|
147
|
+
this.#highlightLayer.removeAllMeshes();
|
|
148
|
+
this.#highlightLayer.dispose();
|
|
149
|
+
this.#highlightLayer = null;
|
|
150
|
+
}
|
|
151
|
+
this.hideMenu();
|
|
152
|
+
this.#animatedNodes = [];
|
|
153
|
+
this.#openingAnimations.forEach((openingAnimation) => openingAnimation.dispose());
|
|
154
|
+
this.#openingAnimations = [];
|
|
155
|
+
}
|
|
156
|
+
|
|
125
157
|
/**
|
|
126
158
|
* Highlights meshes that are children of an animated node when hovered.
|
|
127
|
-
* @
|
|
159
|
+
* @public
|
|
128
160
|
* @param {PickingInfo} pickingInfo - Raycast info from pointer position.
|
|
129
161
|
*/
|
|
130
|
-
|
|
162
|
+
hightlightMeshes(pickingInfo) {
|
|
131
163
|
if (!this.#highlightLayer) {
|
|
132
164
|
this.#highlightLayer = new HighlightLayer("hl_animations", this.#scene);
|
|
133
165
|
}
|
|
@@ -150,52 +182,27 @@ export default class BabylonJSAnimationController {
|
|
|
150
182
|
}
|
|
151
183
|
|
|
152
184
|
/**
|
|
153
|
-
*
|
|
154
|
-
* @
|
|
155
|
-
|
|
156
|
-
#setupPointerObservers() {
|
|
157
|
-
if (this.#openingAnimations.length === 0) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
this.#scene.onPointerObservable.add(this.#onAnimationPointerObservable.bind(this));
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Handles pointer events in the Babylon.js scene for animation interaction.
|
|
165
|
-
* On pointer move, highlights meshes belonging to animated nodes under the cursor.
|
|
166
|
-
* On pointer up (click), disposes any existing GUI and displays the animation control menu for the selected node.
|
|
167
|
-
*
|
|
168
|
-
* @private
|
|
169
|
-
* @param {PointerInfo} pointerInfo - The pointer event information from Babylon.js.
|
|
185
|
+
* Hides and disposes the animation control menu if it exists.
|
|
186
|
+
* @public
|
|
187
|
+
* @returns {void}
|
|
170
188
|
*/
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
this.#hightlightMeshesForAnimation(pickingInfo);
|
|
175
|
-
}
|
|
176
|
-
if (pointerInfo.type === PointerEventTypes.POINTERUP) {
|
|
177
|
-
// Remove any previously created Babylon GUI
|
|
178
|
-
if (this.#advancedDynamicTexture) {
|
|
179
|
-
this.#advancedDynamicTexture.dispose();
|
|
180
|
-
this.#advancedDynamicTexture = null;
|
|
181
|
-
}
|
|
182
|
-
const pickingInfo = this.#scene.pick(pointerInfo.event.clientX, pointerInfo.event.clientY);
|
|
183
|
-
this.#showMenu(pickingInfo);
|
|
184
|
-
}
|
|
189
|
+
hideMenu() {
|
|
190
|
+
this.#openingAnimations.forEach((openingAnimation) => openingAnimation.hideControls());
|
|
191
|
+
this.#canvas.parentElement.querySelectorAll("div.pref-viewer-3d.animation-menu").forEach((menu) => menu.remove());
|
|
185
192
|
}
|
|
186
193
|
|
|
187
194
|
/**
|
|
188
195
|
* Displays the animation control menu for the animated node under the pointer.
|
|
189
|
-
* @
|
|
196
|
+
* @public
|
|
190
197
|
* @param {PickingInfo} pickingInfo - Raycast info from pointer position.
|
|
191
|
-
* @description
|
|
192
|
-
* Creates the GUI if needed and invokes OpeningAnimation.showControls.
|
|
193
198
|
*/
|
|
194
|
-
|
|
199
|
+
showMenu(pickingInfo) {
|
|
195
200
|
if (!pickingInfo?.hit && !pickingInfo?.pickedMesh) {
|
|
196
201
|
return;
|
|
197
202
|
}
|
|
198
203
|
|
|
204
|
+
this.hideMenu();
|
|
205
|
+
|
|
199
206
|
const nodeId = this.#getNodeAnimatedByMesh(pickingInfo.pickedMesh);
|
|
200
207
|
if (!nodeId) {
|
|
201
208
|
return;
|
|
@@ -204,32 +211,7 @@ export default class BabylonJSAnimationController {
|
|
|
204
211
|
if (!openingAnimation) {
|
|
205
212
|
return;
|
|
206
213
|
}
|
|
207
|
-
if (!this.#advancedDynamicTexture) {
|
|
208
|
-
this.#advancedDynamicTexture = AdvancedDynamicTexture.CreateFullscreenUI("UI_Animation");
|
|
209
|
-
}
|
|
210
|
-
openingAnimation.showControls(this.#advancedDynamicTexture);
|
|
211
|
-
}
|
|
212
214
|
|
|
213
|
-
|
|
214
|
-
* Disposes all resources managed by the animation controller.
|
|
215
|
-
* Cleans up the highlight layer, GUI texture, and internal animation/node lists.
|
|
216
|
-
* Should be called when the controller is no longer needed to prevent memory leaks.
|
|
217
|
-
* @public
|
|
218
|
-
*/
|
|
219
|
-
dispose() {
|
|
220
|
-
if (this.#highlightLayer) {
|
|
221
|
-
this.#highlightLayer.dispose();
|
|
222
|
-
this.#highlightLayer = null;
|
|
223
|
-
}
|
|
224
|
-
if (this.#advancedDynamicTexture) {
|
|
225
|
-
this.#advancedDynamicTexture.dispose();
|
|
226
|
-
this.#advancedDynamicTexture = null;
|
|
227
|
-
}
|
|
228
|
-
this.#animatedNodes = [];
|
|
229
|
-
this.#openingAnimations = [];
|
|
230
|
-
const observer = this.#scene.onPointerObservable._observers.find((observer) => observer.callback.name.includes("#onAnimationPointerObservable"));
|
|
231
|
-
if (observer) {
|
|
232
|
-
this.#scene.onPointerObservable.remove(observer);
|
|
233
|
-
}
|
|
215
|
+
openingAnimation.showControls(this.#canvas);
|
|
234
216
|
}
|
|
235
217
|
}
|