@preference-sl/pref-viewer 2.11.0-beta.2 → 2.11.0-beta.20
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 -49
- package/src/babylonjs-animation-controller.js +217 -0
- package/src/babylonjs-animation-opening-menu.js +395 -0
- package/src/babylonjs-animation-opening.js +527 -0
- package/src/babylonjs-controller.js +481 -98
- package/src/file-storage.js +11 -2
- package/src/index.js +18 -772
- package/src/panzoom-controller.js +92 -54
- package/src/pref-viewer-2d.js +25 -12
- package/src/pref-viewer-3d-data.js +3 -2
- package/src/pref-viewer-3d.js +93 -21
- package/src/pref-viewer-dialog.js +146 -0
- 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
|
@@ -1,59 +1,68 @@
|
|
|
1
|
-
|
|
1
|
+
// Explicitly target the ESM bundle so esbuild (platform=node) picks up the default export.
|
|
2
|
+
import Panzoom from "@panzoom/panzoom/dist/panzoom.es.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
* PanzoomController - Encapsulates
|
|
5
|
+
* PanzoomController - Encapsulates logic for managing pan and zoom interactions on a DOM element using the Panzoom library.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Summary:
|
|
8
|
+
* Provides a high-level API to enable, disable, and control pan/zoom interactions for SVG or other DOM content.
|
|
9
|
+
* Manages event listeners for mouse, keyboard, and touch interactions, and tracks the current pan/zoom state.
|
|
10
|
+
* Supports zooming in/out, panning, resetting, and mouse wheel zoom, with customizable options and callbacks.
|
|
11
|
+
*
|
|
12
|
+
* Key Responsibilities:
|
|
13
|
+
* - Initializes and manages a Panzoom instance for a wrapper element.
|
|
14
|
+
* - Handles enabling/disabling pan/zoom and related event listeners.
|
|
15
|
+
* - Tracks and exposes the current pan/zoom state.
|
|
16
|
+
* - Supports keyboard shortcuts, mouse wheel zoom, and context menu prevention.
|
|
17
|
+
* - Provides methods for panning, zooming, and resetting the view.
|
|
18
|
+
* - Invokes a callback when the pan/zoom state changes.
|
|
11
19
|
*
|
|
12
20
|
* Usage:
|
|
13
|
-
* - Instantiate
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
* -
|
|
21
|
+
* - Instantiate: const controller = new PanzoomController(wrapperElement, options, stateChangeCallback);
|
|
22
|
+
* - Enable pan/zoom: controller.enable();
|
|
23
|
+
* - Enable events: controller.enableEvents();
|
|
24
|
+
* - Control view: controller.pan(x, y), controller.zoomIn(), controller.zoomOut(), controller.reset();
|
|
25
|
+
* - Disable pan/zoom and events: controller.disable(), controller.disableEvents();
|
|
17
26
|
*
|
|
18
27
|
* Constructor Parameters:
|
|
19
|
-
* -
|
|
20
|
-
* -
|
|
21
|
-
* -
|
|
28
|
+
* - wrapper (HTMLElement): The DOM element to apply pan/zoom interactions to.
|
|
29
|
+
* - options (object): Configuration options for Panzoom (e.g., minScale, maxScale, step).
|
|
30
|
+
* - changedCallback (function): Optional callback invoked when the pan/zoom state changes.
|
|
22
31
|
*
|
|
23
32
|
* Public Methods:
|
|
24
|
-
* -
|
|
25
|
-
* -
|
|
26
|
-
* -
|
|
27
|
-
* -
|
|
28
|
-
* -
|
|
29
|
-
* -
|
|
30
|
-
* -
|
|
31
|
-
* -
|
|
33
|
+
* - enable(): Enables the Panzoom instance and initializes it if not already enabled.
|
|
34
|
+
* - disable(): Disables the Panzoom instance and removes all event listeners.
|
|
35
|
+
* - enableEvents(): Attaches all required event listeners for interactions.
|
|
36
|
+
* - disableEvents(): Removes all previously attached event listeners.
|
|
37
|
+
* - pan(x, y): Pans the view to the specified coordinates.
|
|
38
|
+
* - reset(): Resets pan and zoom to fit the entire content within the available space.
|
|
39
|
+
* - zoomIn(focal?): Zooms in by one step, optionally centered on a focal point.
|
|
40
|
+
* - zoomOut(focal?): Zooms out by one step, optionally centered on a focal point.
|
|
32
41
|
*
|
|
33
42
|
* Getters:
|
|
34
|
-
* -
|
|
35
|
-
* -
|
|
43
|
+
* - panzoom: Returns the current Panzoom instance or null if not initialized.
|
|
44
|
+
* - state: Returns the current pan/zoom state (moved, scaled, maximized, minimized).
|
|
36
45
|
*
|
|
37
46
|
* Private Methods:
|
|
38
|
-
* -
|
|
39
|
-
* -
|
|
40
|
-
* -
|
|
41
|
-
* -
|
|
42
|
-
* -
|
|
43
|
-
* -
|
|
44
|
-
* -
|
|
45
|
-
* -
|
|
46
|
-
* -
|
|
47
|
-
* -
|
|
48
|
-
* -
|
|
47
|
+
* - #bindHandlers(): Pre-binds reusable event handlers to preserve stable references.
|
|
48
|
+
* - #checkPanzoomState(transform): Updates the internal state and invokes the state change callback.
|
|
49
|
+
* - #resetTransform(): Resets the transform applied to the wrapper element.
|
|
50
|
+
* - #setFocus(): Sets focus on the parent element to enable keyboard interactions.
|
|
51
|
+
* - #onPanzoomStart(e): Handles the start of a pan/zoom interaction.
|
|
52
|
+
* - #onPanzoomChange(e): Handles changes in pan/zoom state.
|
|
53
|
+
* - #onPanzoomEnd(e): Handles the end of a pan/zoom interaction.
|
|
54
|
+
* - #onZoomWithWheel(e): Handles zoom interactions via the mouse wheel.
|
|
55
|
+
* - #enableMouseWheelZoom(): Enables zooming with the mouse wheel.
|
|
56
|
+
* - #disableMouseWheelZoom(): Disables zooming with the mouse wheel.
|
|
57
|
+
* - #getDistanceBetweenPoints(point1, point2): Calculates the Euclidean distance between two points.
|
|
58
|
+
* - #getPointFromEvent(e): Extracts client coordinates from a mouse or touch event.
|
|
49
59
|
*
|
|
50
60
|
* Notes:
|
|
51
61
|
* - Designed to work with the Panzoom library for managing pan/zoom interactions.
|
|
52
|
-
* -
|
|
62
|
+
* - Encapsulates all pan/zoom logic in a single class for clean separation of concerns.
|
|
53
63
|
* - Can be extended or customized by overriding methods or providing additional options.
|
|
54
64
|
*/
|
|
55
65
|
export default class PanzoomController {
|
|
56
|
-
#changedCallback = null;
|
|
57
66
|
#interactionOptions = {
|
|
58
67
|
clickThreshold: 6, // Threshold to avoid false clicks on elements when panning or zooming
|
|
59
68
|
};
|
|
@@ -79,11 +88,40 @@ export default class PanzoomController {
|
|
|
79
88
|
minimized: false,
|
|
80
89
|
};
|
|
81
90
|
#wrapper = null;
|
|
82
|
-
|
|
91
|
+
|
|
92
|
+
#changedCallback = null;
|
|
93
|
+
#handlers = {
|
|
94
|
+
panzoomStart: null,
|
|
95
|
+
panzoomChange: null,
|
|
96
|
+
panzoomEnd: null,
|
|
97
|
+
keyUp: null,
|
|
98
|
+
focus: null,
|
|
99
|
+
blur: null,
|
|
100
|
+
contextMenu: null,
|
|
101
|
+
wheel: null,
|
|
102
|
+
};
|
|
103
|
+
|
|
83
104
|
constructor(wrapper = null, options = {}, changedCallback = null) {
|
|
84
105
|
this.#wrapper = wrapper;
|
|
85
106
|
Object.assign(this.#options, options);
|
|
86
107
|
this.#changedCallback = changedCallback;
|
|
108
|
+
this.#bindHandlers();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Pre-binds reusable event handlers to preserve stable references.
|
|
113
|
+
* @private
|
|
114
|
+
* @returns {void}
|
|
115
|
+
*/
|
|
116
|
+
#bindHandlers() {
|
|
117
|
+
this.#handlers.panzoomStart = this.#onPanzoomStart.bind(this);
|
|
118
|
+
this.#handlers.panzoomChange = this.#onPanzoomChange.bind(this);
|
|
119
|
+
this.#handlers.panzoomEnd = this.#onPanzoomEnd.bind(this);
|
|
120
|
+
this.#handlers.keyUp = this.#onKeyUp.bind(this);
|
|
121
|
+
this.#handlers.focus = this.#enableMouseWheelZoom.bind(this);
|
|
122
|
+
this.#handlers.blur = this.#disableMouseWheelZoom.bind(this);
|
|
123
|
+
this.#handlers.contextMenu = this.#onContextMenu.bind(this);
|
|
124
|
+
this.#handlers.wheel = this.#onZoomWithWheel.bind(this);
|
|
87
125
|
}
|
|
88
126
|
|
|
89
127
|
/**
|
|
@@ -294,7 +332,7 @@ export default class PanzoomController {
|
|
|
294
332
|
if (!this.#panzoom) {
|
|
295
333
|
return;
|
|
296
334
|
}
|
|
297
|
-
this.#wrapper.parentElement.removeEventListener("wheel", this.#
|
|
335
|
+
this.#wrapper.parentElement.removeEventListener("wheel", this.#handlers.wheel);
|
|
298
336
|
}
|
|
299
337
|
|
|
300
338
|
/**
|
|
@@ -309,7 +347,7 @@ export default class PanzoomController {
|
|
|
309
347
|
return;
|
|
310
348
|
}
|
|
311
349
|
this.#disableMouseWheelZoom();
|
|
312
|
-
this.#wrapper.parentElement.addEventListener("wheel", this.#
|
|
350
|
+
this.#wrapper.parentElement.addEventListener("wheel", this.#handlers.wheel);
|
|
313
351
|
}
|
|
314
352
|
|
|
315
353
|
/**
|
|
@@ -363,13 +401,13 @@ export default class PanzoomController {
|
|
|
363
401
|
|
|
364
402
|
this.disableEvents();
|
|
365
403
|
|
|
366
|
-
this.#wrapper.addEventListener("panzoomstart", this.#
|
|
367
|
-
this.#wrapper.addEventListener("panzoomchange", this.#
|
|
368
|
-
this.#wrapper.addEventListener("panzoomend", this.#
|
|
369
|
-
this.#wrapper.parentElement.addEventListener("keyup", this.#
|
|
370
|
-
this.#wrapper.parentElement.addEventListener("focus", this.#
|
|
371
|
-
this.#wrapper.parentElement.addEventListener("blur", this.#
|
|
372
|
-
this.#wrapper.parentElement.addEventListener("contextmenu", this.#
|
|
404
|
+
this.#wrapper.addEventListener("panzoomstart", this.#handlers.panzoomStart);
|
|
405
|
+
this.#wrapper.addEventListener("panzoomchange", this.#handlers.panzoomChange);
|
|
406
|
+
this.#wrapper.addEventListener("panzoomend", this.#handlers.panzoomEnd);
|
|
407
|
+
this.#wrapper.parentElement.addEventListener("keyup", this.#handlers.keyUp);
|
|
408
|
+
this.#wrapper.parentElement.addEventListener("focus", this.#handlers.focus, true);
|
|
409
|
+
this.#wrapper.parentElement.addEventListener("blur", this.#handlers.blur, true);
|
|
410
|
+
this.#wrapper.parentElement.addEventListener("contextmenu", this.#handlers.contextMenu);
|
|
373
411
|
this.#wrapper.parentElement.setAttribute("tabindex", 0);
|
|
374
412
|
this.#setFocus();
|
|
375
413
|
}
|
|
@@ -385,13 +423,13 @@ export default class PanzoomController {
|
|
|
385
423
|
return;
|
|
386
424
|
}
|
|
387
425
|
this.#wrapper.parentElement.removeAttribute("tabindex");
|
|
388
|
-
this.#wrapper.removeEventListener("panzoomstart", this.#
|
|
389
|
-
this.#wrapper.removeEventListener("panzoomchange", this.#
|
|
390
|
-
this.#wrapper.removeEventListener("panzoomend", this.#
|
|
391
|
-
this.#wrapper.parentElement.removeEventListener("keyup", this.#
|
|
392
|
-
this.#wrapper.parentElement.removeEventListener("focus", this.#
|
|
393
|
-
this.#wrapper.parentElement.removeEventListener("blur", this.#
|
|
394
|
-
this.#wrapper.parentElement.removeEventListener("contextmenu", this.#
|
|
426
|
+
this.#wrapper.removeEventListener("panzoomstart", this.#handlers.panzoomStart);
|
|
427
|
+
this.#wrapper.removeEventListener("panzoomchange", this.#handlers.panzoomChange);
|
|
428
|
+
this.#wrapper.removeEventListener("panzoomend", this.#handlers.panzoomEnd);
|
|
429
|
+
this.#wrapper.parentElement.removeEventListener("keyup", this.#handlers.keyUp);
|
|
430
|
+
this.#wrapper.parentElement.removeEventListener("focus", this.#handlers.focus);
|
|
431
|
+
this.#wrapper.parentElement.removeEventListener("blur", this.#handlers.blur);
|
|
432
|
+
this.#wrapper.parentElement.removeEventListener("contextmenu", this.#handlers.contextMenu);
|
|
395
433
|
}
|
|
396
434
|
|
|
397
435
|
/**
|
package/src/pref-viewer-2d.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import SVGResolver from "./svg-resolver.js";
|
|
2
2
|
import PanzoomController from "./panzoom-controller.js";
|
|
3
|
+
import { PrefViewer2DStyles } from "./styles.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* PrefViewer2D - Custom element for rendering and interacting with 2D SVG content.
|
|
@@ -46,7 +47,7 @@ import PanzoomController from "./panzoom-controller.js";
|
|
|
46
47
|
* Notes on extensibility
|
|
47
48
|
* - Modeled for easy addition of other input sources or interaction modes (e.g., selection callbacks).
|
|
48
49
|
*/
|
|
49
|
-
export class PrefViewer2D extends HTMLElement {
|
|
50
|
+
export default class PrefViewer2D extends HTMLElement {
|
|
50
51
|
// State flags
|
|
51
52
|
#isInitialized = false;
|
|
52
53
|
#isLoaded = false;
|
|
@@ -68,6 +69,10 @@ export class PrefViewer2D extends HTMLElement {
|
|
|
68
69
|
#wrapper = null; // Panzoom element
|
|
69
70
|
#panzoomController = null; // PanzoomController instance
|
|
70
71
|
|
|
72
|
+
#handlers = {
|
|
73
|
+
onPanzoomChanged: null,
|
|
74
|
+
};
|
|
75
|
+
|
|
71
76
|
/**
|
|
72
77
|
* Create a new instance of the 2D viewer component.
|
|
73
78
|
* The constructor only calls super(); heavy initialization happens in connectedCallback.
|
|
@@ -114,6 +119,7 @@ export class PrefViewer2D extends HTMLElement {
|
|
|
114
119
|
/**
|
|
115
120
|
* Called when the element is inserted into the DOM.
|
|
116
121
|
* Sets up DOM nodes, initial visibility and starts loading the SVG if provided.
|
|
122
|
+
* @public
|
|
117
123
|
* @returns {void}
|
|
118
124
|
*/
|
|
119
125
|
connectedCallback() {
|
|
@@ -127,6 +133,7 @@ export class PrefViewer2D extends HTMLElement {
|
|
|
127
133
|
/**
|
|
128
134
|
* Called when the element is removed from the DOM.
|
|
129
135
|
* Disables the PanzoomController to clean up event listeners and resources.
|
|
136
|
+
* @public
|
|
130
137
|
* @returns {void}
|
|
131
138
|
*/
|
|
132
139
|
disconnectedCallback() {
|
|
@@ -143,8 +150,9 @@ export class PrefViewer2D extends HTMLElement {
|
|
|
143
150
|
#createDOMElements() {
|
|
144
151
|
this.#wrapper = document.createElement("div");
|
|
145
152
|
this.append(this.#wrapper);
|
|
153
|
+
|
|
146
154
|
const style = document.createElement("style");
|
|
147
|
-
style.textContent =
|
|
155
|
+
style.textContent = PrefViewer2DStyles;
|
|
148
156
|
this.append(style);
|
|
149
157
|
}
|
|
150
158
|
|
|
@@ -166,7 +174,8 @@ export class PrefViewer2D extends HTMLElement {
|
|
|
166
174
|
* @returns {void}
|
|
167
175
|
*/
|
|
168
176
|
#initializePanzoom() {
|
|
169
|
-
this.#
|
|
177
|
+
this.#handlers.onPanzoomChanged = this.#onPanzoomChanged.bind(this);
|
|
178
|
+
this.#panzoomController = new PanzoomController(this.#wrapper, undefined, this.#handlers.onPanzoomChanged);
|
|
170
179
|
}
|
|
171
180
|
|
|
172
181
|
/**
|
|
@@ -221,9 +230,9 @@ export class PrefViewer2D extends HTMLElement {
|
|
|
221
230
|
const error = "PrefViewer2D: Error in SVG provided for loading. Ensure the SVG is a URL to an SVG file, a string containing a SVG, or a string containing a base64-encoded SVG.";
|
|
222
231
|
const detail = { error: new Error(error) };
|
|
223
232
|
const customEventOptions = {
|
|
224
|
-
bubbles: true,
|
|
225
|
-
cancelable:
|
|
226
|
-
composed:
|
|
233
|
+
bubbles: true, // indicates whether the event bubbles up through the DOM tree or not
|
|
234
|
+
cancelable: true, // indicates whether the event can be canceled, and therefore prevented as if the event never happened
|
|
235
|
+
composed: false, // indicates whether or not the event will propagate across the shadow DOM boundary into the standard DOM
|
|
227
236
|
detail: detail,
|
|
228
237
|
};
|
|
229
238
|
this.dispatchEvent(new CustomEvent("drawing-error", customEventOptions));
|
|
@@ -238,8 +247,8 @@ export class PrefViewer2D extends HTMLElement {
|
|
|
238
247
|
#onLoaded() {
|
|
239
248
|
const customEventOptions = {
|
|
240
249
|
bubbles: true,
|
|
241
|
-
cancelable:
|
|
242
|
-
composed:
|
|
250
|
+
cancelable: true,
|
|
251
|
+
composed: false,
|
|
243
252
|
};
|
|
244
253
|
this.dispatchEvent(new CustomEvent("drawing-loaded", customEventOptions));
|
|
245
254
|
|
|
@@ -258,8 +267,8 @@ export class PrefViewer2D extends HTMLElement {
|
|
|
258
267
|
#onLoading() {
|
|
259
268
|
const customEventOptions = {
|
|
260
269
|
bubbles: true,
|
|
261
|
-
cancelable:
|
|
262
|
-
composed:
|
|
270
|
+
cancelable: true,
|
|
271
|
+
composed: false,
|
|
263
272
|
};
|
|
264
273
|
this.dispatchEvent(new CustomEvent("drawing-loading", customEventOptions));
|
|
265
274
|
|
|
@@ -285,10 +294,11 @@ export class PrefViewer2D extends HTMLElement {
|
|
|
285
294
|
#onPanzoomChanged(state) {
|
|
286
295
|
const customEventOptions = {
|
|
287
296
|
bubbles: true,
|
|
288
|
-
cancelable:
|
|
289
|
-
composed:
|
|
297
|
+
cancelable: true,
|
|
298
|
+
composed: false,
|
|
290
299
|
detail: state,
|
|
291
300
|
};
|
|
301
|
+
customEventOptions.detail.desde2d = "true";
|
|
292
302
|
this.dispatchEvent(new CustomEvent("drawing-zoom-changed", customEventOptions));
|
|
293
303
|
}
|
|
294
304
|
|
|
@@ -348,6 +358,9 @@ export class PrefViewer2D extends HTMLElement {
|
|
|
348
358
|
* - Resolves to { success: true, error: null } when the SVG was accepted and the component has started rendering.
|
|
349
359
|
*/
|
|
350
360
|
async load(svgConfig) {
|
|
361
|
+
if (!this.#svgResolver) {
|
|
362
|
+
this.#svgResolver = new SVGResolver(this.#svg);
|
|
363
|
+
}
|
|
351
364
|
if (!svgConfig || !(await this.#svgResolver.getSVG(svgConfig))) {
|
|
352
365
|
const errorDetail = this.#onError();
|
|
353
366
|
return { success: false, ...errorDetail };
|
|
@@ -46,7 +46,7 @@ export class ContainerData {
|
|
|
46
46
|
this.update.pending = true;
|
|
47
47
|
this.update.storage = storage;
|
|
48
48
|
this.update.success = false;
|
|
49
|
-
this.update.show = show !== undefined ? show : this.update.show;
|
|
49
|
+
this.update.show = show !== undefined ? show : this.update.show !== null ? this.update.show : this.show;
|
|
50
50
|
}
|
|
51
51
|
setPendingCacheData(size = 0, timeStamp = null) {
|
|
52
52
|
this.update.size = size;
|
|
@@ -62,7 +62,7 @@ export class ContainerData {
|
|
|
62
62
|
return this.visible === true;
|
|
63
63
|
}
|
|
64
64
|
get mustBeShown() {
|
|
65
|
-
return this.show === true;
|
|
65
|
+
return this.update.show !== null ? this.update.show === true : this.show === true;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -152,6 +152,7 @@ export class CameraData {
|
|
|
152
152
|
if (success) {
|
|
153
153
|
this.update.success = true;
|
|
154
154
|
this.value = this.update.value;
|
|
155
|
+
this.locked = this.update.locked;
|
|
155
156
|
} else {
|
|
156
157
|
this.update.success = false;
|
|
157
158
|
}
|
package/src/pref-viewer-3d.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { ContainerData, MaterialData
|
|
1
|
+
import { CameraData, ContainerData, MaterialData } from "./pref-viewer-3d-data.js";
|
|
2
2
|
import BabylonJSController from "./babylonjs-controller.js";
|
|
3
|
+
import { PrefViewer3DStyles } from "./styles.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* PrefViewer3D - Custom Web Component for interactive 3D visualization and configuration.
|
|
@@ -31,9 +32,14 @@ import BabylonJSController from "./babylonjs-controller.js";
|
|
|
31
32
|
* - showEnvironment(): Shows the 3D environment/scene.
|
|
32
33
|
* - hideEnvironment(): Hides the 3D environment/scene.
|
|
33
34
|
* - downloadModelGLB(): Downloads the current 3D model as a GLB file.
|
|
35
|
+
* - downloadModelGLTF(): Downloads the current 3D model as a glTF ZIP file.
|
|
34
36
|
* - downloadModelUSDZ(): Downloads the current 3D model as a USDZ file.
|
|
35
37
|
* - downloadModelAndSceneGLB(): Downloads both the model and scene as a GLB file.
|
|
38
|
+
* - downloadModelAndSceneGLTF(): Downloads both the model and scene as a glTF ZIP file.
|
|
36
39
|
* - downloadModelAndSceneUSDZ(): Downloads both the model and scene as a USDZ file.
|
|
40
|
+
* - downloadSceneGLB(): Downloads the environment as a GLB file.
|
|
41
|
+
* - downloadSceneGLTF(): Downloads the environment as a glTF ZIP file.
|
|
42
|
+
* - downloadSceneUSDZ(): Downloads the environment as a USDZ file.
|
|
37
43
|
*
|
|
38
44
|
* Public Properties:
|
|
39
45
|
* - isInitialized: Indicates whether the component has completed initialization.
|
|
@@ -51,7 +57,7 @@ import BabylonJSController from "./babylonjs-controller.js";
|
|
|
51
57
|
* - Designed for extensibility and integration in product configurators and visualization tools.
|
|
52
58
|
* - All resource management and rendering operations are performed asynchronously for performance.
|
|
53
59
|
*/
|
|
54
|
-
export class PrefViewer3D extends HTMLElement {
|
|
60
|
+
export default class PrefViewer3D extends HTMLElement {
|
|
55
61
|
// State flags
|
|
56
62
|
#isInitialized = false;
|
|
57
63
|
#isLoaded = false;
|
|
@@ -124,6 +130,7 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
124
130
|
* Called when the element is added to the DOM.
|
|
125
131
|
* Creates the DOM structure, sets initial visibility, initializes component data, and sets up the BabylonJSController.
|
|
126
132
|
* Performs heavy initialization tasks required for the 3D viewer.
|
|
133
|
+
* @public
|
|
127
134
|
* @returns {void}
|
|
128
135
|
*/
|
|
129
136
|
connectedCallback() {
|
|
@@ -131,11 +138,13 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
131
138
|
this.#setInitialVisibility();
|
|
132
139
|
this.#initializeData();
|
|
133
140
|
this.#initializeBabylonJS();
|
|
141
|
+
this.#isInitialized = true;
|
|
134
142
|
}
|
|
135
143
|
|
|
136
144
|
/**
|
|
137
145
|
* Called when the element is removed from the DOM.
|
|
138
146
|
* Disables the BabylonJSController to clean up resources and event listeners associated with the 3D viewer.
|
|
147
|
+
* @public
|
|
139
148
|
* @returns {void}
|
|
140
149
|
*/
|
|
141
150
|
disconnectedCallback() {
|
|
@@ -152,10 +161,12 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
152
161
|
#createDOMElements() {
|
|
153
162
|
this.#wrapper = document.createElement("div");
|
|
154
163
|
this.append(this.#wrapper);
|
|
164
|
+
|
|
155
165
|
this.#canvas = document.createElement("canvas");
|
|
156
166
|
this.#wrapper.appendChild(this.#canvas);
|
|
167
|
+
|
|
157
168
|
const style = document.createElement("style");
|
|
158
|
-
style.textContent =
|
|
169
|
+
style.textContent = PrefViewer3DStyles;
|
|
159
170
|
this.append(style);
|
|
160
171
|
}
|
|
161
172
|
|
|
@@ -303,9 +314,9 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
303
314
|
*/
|
|
304
315
|
#onLoading() {
|
|
305
316
|
const customEventOptions = {
|
|
306
|
-
bubbles: true,
|
|
307
|
-
cancelable:
|
|
308
|
-
composed:
|
|
317
|
+
bubbles: true, // indicates whether the event bubbles up through the DOM tree or not
|
|
318
|
+
cancelable: true, // indicates whether the event can be canceled, and therefore prevented as if the event never happened
|
|
319
|
+
composed: false, // indicates whether or not the event will propagate across the shadow DOM boundary into the standard DOM
|
|
309
320
|
};
|
|
310
321
|
this.dispatchEvent(new CustomEvent("scene-loading", customEventOptions));
|
|
311
322
|
|
|
@@ -351,8 +362,8 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
351
362
|
|
|
352
363
|
const customEventOptions = {
|
|
353
364
|
bubbles: true,
|
|
354
|
-
cancelable:
|
|
355
|
-
composed:
|
|
365
|
+
cancelable: true,
|
|
366
|
+
composed: false,
|
|
356
367
|
detail: detail,
|
|
357
368
|
};
|
|
358
369
|
this.dispatchEvent(new CustomEvent("scene-loaded", customEventOptions));
|
|
@@ -375,8 +386,8 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
375
386
|
#onSettingOptions() {
|
|
376
387
|
const customEventOptions = {
|
|
377
388
|
bubbles: true,
|
|
378
|
-
cancelable:
|
|
379
|
-
composed:
|
|
389
|
+
cancelable: true,
|
|
390
|
+
composed: false,
|
|
380
391
|
};
|
|
381
392
|
this.dispatchEvent(new CustomEvent("scene-setting-options", customEventOptions));
|
|
382
393
|
|
|
@@ -413,11 +424,11 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
413
424
|
tried: toSetDetail,
|
|
414
425
|
success: settedDetail,
|
|
415
426
|
};
|
|
416
|
-
|
|
427
|
+
|
|
417
428
|
const customEventOptions = {
|
|
418
429
|
bubbles: true,
|
|
419
|
-
cancelable:
|
|
420
|
-
composed:
|
|
430
|
+
cancelable: true,
|
|
431
|
+
composed: false,
|
|
421
432
|
detail: detail,
|
|
422
433
|
};
|
|
423
434
|
this.dispatchEvent(new CustomEvent("scene-set-options", customEventOptions));
|
|
@@ -455,6 +466,7 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
455
466
|
show() {
|
|
456
467
|
this.#isVisible = true;
|
|
457
468
|
this.setAttribute("visible", "true");
|
|
469
|
+
this.#canvas.focus();
|
|
458
470
|
}
|
|
459
471
|
|
|
460
472
|
/**
|
|
@@ -567,7 +579,19 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
567
579
|
if (!this.#babylonJSController) {
|
|
568
580
|
return;
|
|
569
581
|
}
|
|
570
|
-
this.#babylonJSController.
|
|
582
|
+
this.#babylonJSController.downloadGLB(1);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Downloads the current 3D model as a glTF file (ZIP with gltf and all resources (textures, buffers, etc.)).
|
|
587
|
+
* @public
|
|
588
|
+
* @returns {void}
|
|
589
|
+
*/
|
|
590
|
+
downloadModelGLTF() {
|
|
591
|
+
if (!this.#babylonJSController) {
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
this.#babylonJSController.downloadGLTF(1);
|
|
571
595
|
}
|
|
572
596
|
|
|
573
597
|
/**
|
|
@@ -579,11 +603,35 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
579
603
|
if (!this.#babylonJSController) {
|
|
580
604
|
return;
|
|
581
605
|
}
|
|
582
|
-
this.#babylonJSController.
|
|
606
|
+
this.#babylonJSController.downloadUSDZ(1);
|
|
583
607
|
}
|
|
584
608
|
|
|
585
609
|
/**
|
|
586
|
-
* Downloads
|
|
610
|
+
* Downloads the current 3D complete scene (model and environment) as a GLB file.
|
|
611
|
+
* @public
|
|
612
|
+
* @returns {void}
|
|
613
|
+
*/
|
|
614
|
+
downloadModelAndSceneGLB() {
|
|
615
|
+
if (!this.#babylonJSController) {
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
this.#babylonJSController.downloadModelGLB(0);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Downloads the current 3D complete scene (model and environment) as a glTF file (ZIP with gltf and all resources (textures, buffers, etc.)).
|
|
623
|
+
* @public
|
|
624
|
+
* @returns {void}
|
|
625
|
+
*/
|
|
626
|
+
downloadModelAndSceneGLTF() {
|
|
627
|
+
if (!this.#babylonJSController) {
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
this.#babylonJSController.downloadGLTF(0);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Downloads the current 3D complete scene (model and environment) as a USDZ file.
|
|
587
635
|
* @public
|
|
588
636
|
* @returns {void}
|
|
589
637
|
*/
|
|
@@ -591,19 +639,43 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
591
639
|
if (!this.#babylonJSController) {
|
|
592
640
|
return;
|
|
593
641
|
}
|
|
594
|
-
this.#babylonJSController.
|
|
642
|
+
this.#babylonJSController.downloadUSDZ(0);
|
|
595
643
|
}
|
|
596
644
|
|
|
597
645
|
/**
|
|
598
|
-
* Downloads
|
|
646
|
+
* Downloads the current 3D environment as a GLB file.
|
|
599
647
|
* @public
|
|
600
648
|
* @returns {void}
|
|
601
649
|
*/
|
|
602
|
-
|
|
650
|
+
downloadSceneGLB() {
|
|
651
|
+
if (!this.#babylonJSController) {
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
this.#babylonJSController.downloadGLB(2);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Downloads the current 3D environment as a glTF file (ZIP with gltf and all resources (textures, buffers, etc.)).
|
|
659
|
+
* @public
|
|
660
|
+
* @returns {void}
|
|
661
|
+
*/
|
|
662
|
+
downloadSceneGLTF() {
|
|
663
|
+
if (!this.#babylonJSController) {
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
this.#babylonJSController.downloadGLTF(2);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Downloads the current 3D environment as a USDZ file.
|
|
671
|
+
* @public
|
|
672
|
+
* @returns {void}
|
|
673
|
+
*/
|
|
674
|
+
downloadSceneUSDZ() {
|
|
603
675
|
if (!this.#babylonJSController) {
|
|
604
676
|
return;
|
|
605
677
|
}
|
|
606
|
-
this.#babylonJSController.
|
|
678
|
+
this.#babylonJSController.downloadUSDZ(2);
|
|
607
679
|
}
|
|
608
680
|
|
|
609
681
|
/**
|
|
@@ -632,4 +704,4 @@ export class PrefViewer3D extends HTMLElement {
|
|
|
632
704
|
get isVisible() {
|
|
633
705
|
return this.#isVisible;
|
|
634
706
|
}
|
|
635
|
-
}
|
|
707
|
+
}
|