@preference-sl/pref-viewer 2.11.0-beta.8 → 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 +233 -113
- package/src/file-storage.js +11 -2
- package/src/index.js +18 -866
- 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 +71 -46
- 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/index.js
CHANGED
|
@@ -1,871 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* PrefViewer - Custom Web Component for advanced 2D and 3D product visualization and configuration.
|
|
8
|
-
*
|
|
9
|
-
* Overview:
|
|
10
|
-
* - Encapsulates both 2D (SVG) and 3D (Babylon.js) viewers, supporting glTF/GLB models, environments, and drawings.
|
|
11
|
-
* - Loads assets from remote URLs, Base64 data URIs, and IndexedDB sources.
|
|
12
|
-
* - Provides a unified API for loading models, scenes, drawings, materials, and configuration via attributes or methods.
|
|
13
|
-
* - Manages an internal task queue for sequential processing of viewer operations.
|
|
14
|
-
* - Emits custom events for loading, errors, and state changes to facilitate integration.
|
|
15
|
-
* - Supports downloading models and scenes in GLB and USDZ formats.
|
|
16
|
-
* - Automatically updates the viewer when reactive attributes change.
|
|
17
|
-
*
|
|
18
|
-
* Usage:
|
|
19
|
-
* - Use as a custom HTML element: <pref-viewer ...>
|
|
20
|
-
* - Configure via attributes (config, model, scene, materials, drawing, options, mode).
|
|
21
|
-
* - Control viewer mode, visibility, and downloads via public methods.
|
|
22
|
-
*
|
|
23
|
-
* Reactive Attributes:
|
|
24
|
-
* - config: URL or Base64 for configuration file.
|
|
25
|
-
* - model: URL or Base64 for 3D model (glTF/GLB).
|
|
26
|
-
* - scene: URL or Base64 for environment/scene (glTF/GLB).
|
|
27
|
-
* - materials: URL or Base64 for materials definition.
|
|
28
|
-
* - drawing: URL or Base64 for SVG drawing.
|
|
29
|
-
* - options: JSON string for viewer options.
|
|
30
|
-
* - mode: Viewer mode ("2d" or "3d").
|
|
31
|
-
*
|
|
32
|
-
* Public Methods:
|
|
33
|
-
* - loadConfig(config): Loads a configuration object or JSON string.
|
|
34
|
-
* - loadModel(model): Loads a model object or JSON string.
|
|
35
|
-
* - loadScene(scene): Loads a scene/environment object or JSON string.
|
|
36
|
-
* - loadMaterials(materials): Loads materials object or JSON string.
|
|
37
|
-
* - loadDrawing(drawing): Loads a drawing object or JSON string.
|
|
38
|
-
* - setOptions(options): Sets viewer options from an object or JSON string.
|
|
39
|
-
* - setMode(mode): Sets the viewer mode to "2d" or "3d" and updates component visibility.
|
|
40
|
-
* - showModel(): Shows the 3D model.
|
|
41
|
-
* - hideModel(): Hides the 3D model.
|
|
42
|
-
* - showScene(): Shows the 3D environment/scene.
|
|
43
|
-
* - hideScene(): Hides the 3D environment/scene.
|
|
44
|
-
* - zoomCenter(): Centers the 2D drawing view.
|
|
45
|
-
* - zoomExtentsAll(): Zooms the 2D drawing to fit all content.
|
|
46
|
-
* - zoomIn(): Zooms in on the 2D drawing.
|
|
47
|
-
* - zoomOut(): Zooms out of the 2D drawing.
|
|
48
|
-
* - downloadModelGLB(): Downloads the current 3D model as a GLB file.
|
|
49
|
-
* - downloadModelGLTF(): Downloads the current 3D model as a glTF ZIP file.
|
|
50
|
-
* - downloadModelUSDZ(): Downloads the current 3D model as a USDZ file.
|
|
51
|
-
* - downloadModelAndSceneGLB(): Downloads both the model and scene as a GLB file.
|
|
52
|
-
* - downloadModelAndSceneGLTF(): Downloads both the model and scene as a glTF ZIP file.
|
|
53
|
-
* - downloadModelAndSceneUSDZ(): Downloads both the model and scene as a USDZ file.
|
|
54
|
-
* - downloadSceneGLB(): Downloads the environment as a GLB file.
|
|
55
|
-
* - downloadSceneGLTF(): Downloads the environment as a glTF ZIP file.
|
|
56
|
-
* - downloadSceneUSDZ(): Downloads the environment as a USDZ file.
|
|
57
|
-
*
|
|
58
|
-
* Public Properties:
|
|
59
|
-
* - isInitialized: Indicates if the viewer is initialized.
|
|
60
|
-
* - isLoaded: Indicates if the viewer has finished loading.
|
|
61
|
-
* - isLoading: Indicates if the viewer is currently loading.
|
|
62
|
-
* - isMode2D: Indicates if the viewer is in 2D mode.
|
|
63
|
-
* - isMode3D: Indicates if the viewer is in 3D mode.
|
|
64
|
-
*
|
|
65
|
-
* Events:
|
|
66
|
-
* - "scene-loading": Dispatched when a 3D loading operation starts.
|
|
67
|
-
* - "scene-loaded": Dispatched when a 3D loading operation completes.
|
|
68
|
-
* - "drawing-loading": Dispatched when a 2D drawing loading operation starts.
|
|
69
|
-
* - "drawing-loaded": Dispatched when a 2D drawing loading operation completes.
|
|
70
|
-
* - "drawing-zoom-changed": Dispatched when the 2D drawing zoom/pan state changes.
|
|
71
|
-
*
|
|
72
|
-
* Notes:
|
|
73
|
-
* - Automatically creates and manages 2D and 3D viewer components in its shadow DOM.
|
|
74
|
-
* - Processes tasks sequentially to ensure consistent state.
|
|
75
|
-
* - Designed for extensibility and integration in product configurators and visualization tools.
|
|
76
|
-
*/
|
|
77
|
-
class PrefViewer extends HTMLElement {
|
|
78
|
-
#isInitialized = false;
|
|
79
|
-
#isLoaded = false;
|
|
80
|
-
#isLoading = false;
|
|
81
|
-
#mode = "3d";
|
|
82
|
-
|
|
83
|
-
#taskQueue = [];
|
|
84
|
-
|
|
85
|
-
#component2D = null;
|
|
86
|
-
#component3D = null;
|
|
87
|
-
#dialog = null;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Creates a new PrefViewer instance and attaches a shadow DOM.
|
|
91
|
-
* Initializes internal state and component references.
|
|
92
|
-
* @public
|
|
93
|
-
*/
|
|
94
|
-
constructor() {
|
|
95
|
-
super();
|
|
96
|
-
this.attachShadow({ mode: "open" });
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Returns the list of attributes to observe for changes.
|
|
101
|
-
* @public
|
|
102
|
-
* @returns {string[]} Array of attribute names to observe.
|
|
103
|
-
*/
|
|
104
|
-
static get observedAttributes() {
|
|
105
|
-
return ["config", "drawing", "materials", "mode", "model", "scene", "options", "show-model", "show-scene"];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Observes changes to specific attributes and triggers corresponding actions.
|
|
110
|
-
* Loads configuration, drawing, model, scene, materials, or options when their attributes change.
|
|
111
|
-
* Toggles model or scene visibility when "show-model" or "show-scene" attributes change.
|
|
112
|
-
* @public
|
|
113
|
-
* @param {string} name - The name of the changed attribute.
|
|
114
|
-
* @param {*} _old - The previous value of the attribute (unused).
|
|
115
|
-
* @param {*} value - The new value of the attribute.
|
|
116
|
-
* @returns {void}
|
|
117
|
-
*/
|
|
118
|
-
attributeChangedCallback(name, _old, value) {
|
|
119
|
-
switch (name) {
|
|
120
|
-
case "config":
|
|
121
|
-
this.loadConfig(value);
|
|
122
|
-
break;
|
|
123
|
-
case "drawing":
|
|
124
|
-
this.loadDrawing(value);
|
|
125
|
-
break;
|
|
126
|
-
case "materials":
|
|
127
|
-
this.loadMaterials(value);
|
|
128
|
-
break;
|
|
129
|
-
case "mode":
|
|
130
|
-
if (_old === value || value.toLowerCase() === this.#mode) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
this.setMode(value.toLowerCase());
|
|
134
|
-
break;
|
|
135
|
-
case "model":
|
|
136
|
-
this.loadModel(value);
|
|
137
|
-
break;
|
|
138
|
-
case "scene":
|
|
139
|
-
this.loadScene(value);
|
|
140
|
-
break;
|
|
141
|
-
case "options":
|
|
142
|
-
this.setOptions(value);
|
|
143
|
-
break;
|
|
144
|
-
case "show-model":
|
|
145
|
-
if (_old === value) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
const showModel = value.toLowerCase() === "true";
|
|
149
|
-
showModel ? this.showModel() : this.hideModel();
|
|
150
|
-
break;
|
|
151
|
-
case "show-scene":
|
|
152
|
-
if (_old === value) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
const showScene = value.toLowerCase() === "true";
|
|
156
|
-
showScene ? this.showScene() : this.hideScene();
|
|
157
|
-
break;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Called when the element is inserted into the DOM.
|
|
163
|
-
* Initializes the 3D and 2D viewer components and starts processing tasks.
|
|
164
|
-
* @public
|
|
165
|
-
* @returns {void|boolean} Returns false if initialization fails; otherwise void.
|
|
166
|
-
*/
|
|
167
|
-
connectedCallback() {
|
|
168
|
-
this.#createComponent3D();
|
|
169
|
-
this.#createComponent2D();
|
|
170
|
-
|
|
171
|
-
if (!this.hasAttribute("mode")) {
|
|
172
|
-
this.setMode();
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
this.#isInitialized = true;
|
|
176
|
-
this.#processNextTask();
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Creates and appends the 2D viewer component to the shadow DOM.
|
|
181
|
-
* Sets the "visible" attribute to true by default.
|
|
182
|
-
* @private
|
|
183
|
-
* @returns {void}
|
|
184
|
-
*/
|
|
185
|
-
#createComponent2D() {
|
|
186
|
-
this.#component2D = document.createElement("pref-viewer-2d");
|
|
187
|
-
this.#component2D.setAttribute("visible", "false");
|
|
188
|
-
this.#component2D.addEventListener("drawing-zoom-changed", this.#on2DZoomChanged.bind(this));
|
|
189
|
-
this.shadowRoot.appendChild(this.#component2D);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Creates and appends the 3D viewer component to the shadow DOM.
|
|
194
|
-
* Sets the "visible" attribute to true by default.
|
|
195
|
-
* @private
|
|
196
|
-
* @returns {void}
|
|
197
|
-
*/
|
|
198
|
-
#createComponent3D() {
|
|
199
|
-
this.#component3D = document.createElement("pref-viewer-3d");
|
|
200
|
-
this.#component3D.setAttribute("visible", "false");
|
|
201
|
-
this.shadowRoot.appendChild(this.#component3D);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Adds a new task to the internal queue for processing.
|
|
206
|
-
* If the viewer is initialized and not currently loading, immediately processes the next task.
|
|
207
|
-
* @private
|
|
208
|
-
* @param {*} value - The payload or data for the task.
|
|
209
|
-
* @param {string} type - The type of task (see PrefViewerTask.Types).
|
|
210
|
-
* @returns {void}
|
|
211
|
-
*/
|
|
212
|
-
#addTaskToQueue(value, type) {
|
|
213
|
-
this.#taskQueue.push(new PrefViewerTask(value, type));
|
|
214
|
-
if (this.#isInitialized && !this.#isLoading) {
|
|
215
|
-
this.#processNextTask();
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Processes the next task in the queue, if any.
|
|
221
|
-
* Dispatches the task to the appropriate handler based on its type.
|
|
222
|
-
* @private
|
|
223
|
-
* @returns {boolean|void} Returns false if the queue is empty; otherwise void.
|
|
224
|
-
*/
|
|
225
|
-
#processNextTask() {
|
|
226
|
-
if (!this.#taskQueue.length) {
|
|
227
|
-
return false;
|
|
228
|
-
}
|
|
229
|
-
const task = this.#taskQueue[0];
|
|
230
|
-
this.#taskQueue.shift();
|
|
231
|
-
switch (task.type) {
|
|
232
|
-
case PrefViewerTask.Types.Config:
|
|
233
|
-
this.#processConfig(task.value);
|
|
234
|
-
break;
|
|
235
|
-
case PrefViewerTask.Types.Drawing:
|
|
236
|
-
this.#processDrawing(task.value);
|
|
237
|
-
break;
|
|
238
|
-
case PrefViewerTask.Types.Environment:
|
|
239
|
-
this.#processEnvironment(task.value);
|
|
240
|
-
break;
|
|
241
|
-
case PrefViewerTask.Types.Materials:
|
|
242
|
-
this.#processMaterials(task.value);
|
|
243
|
-
break;
|
|
244
|
-
case PrefViewerTask.Types.Model:
|
|
245
|
-
this.#processModel(task.value);
|
|
246
|
-
break;
|
|
247
|
-
case PrefViewerTask.Types.Options:
|
|
248
|
-
this.#processOptions(task.value);
|
|
249
|
-
break;
|
|
250
|
-
case PrefViewerTask.Types.Visibility:
|
|
251
|
-
this.#processVisibility(task.value);
|
|
252
|
-
break;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Handles the start of a 3D loading operation.
|
|
258
|
-
* Updates loading state, sets attributes, and dispatches a "scene-loading" event.
|
|
259
|
-
* @private
|
|
260
|
-
* @returns {void}
|
|
261
|
-
*/
|
|
262
|
-
#on3DLoading() {
|
|
263
|
-
this.#isLoaded = false;
|
|
264
|
-
this.#isLoading = true;
|
|
265
|
-
|
|
266
|
-
this.removeAttribute("loaded-3d");
|
|
267
|
-
this.setAttribute("loading-3d", "");
|
|
268
|
-
|
|
269
|
-
const customEventOptions = {
|
|
270
|
-
bubbles: true,
|
|
271
|
-
cancelable: false,
|
|
272
|
-
composed: true,
|
|
273
|
-
};
|
|
274
|
-
this.dispatchEvent(new CustomEvent("scene-loading", customEventOptions));
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Handles the completion of a 3D loading operation.
|
|
279
|
-
* Updates loading state, sets attributes, dispatches a "scene-loaded" event, and processes the next task.
|
|
280
|
-
* @private
|
|
281
|
-
* @param {object} [detail] - Optional details to include in the event.
|
|
282
|
-
* @returns {void}
|
|
283
|
-
*/
|
|
284
|
-
#on3DLoaded(detail) {
|
|
285
|
-
this.#isLoaded = true;
|
|
286
|
-
this.#isLoading = false;
|
|
287
|
-
|
|
288
|
-
this.removeAttribute("loading-3d");
|
|
289
|
-
this.setAttribute("loaded-3d", "");
|
|
290
|
-
|
|
291
|
-
const customEventOptions = {
|
|
292
|
-
bubbles: true,
|
|
293
|
-
cancelable: true,
|
|
294
|
-
composed: true,
|
|
295
|
-
};
|
|
296
|
-
if (detail) {
|
|
297
|
-
customEventOptions.detail = detail;
|
|
298
|
-
}
|
|
299
|
-
this.dispatchEvent(new CustomEvent("scene-loaded", customEventOptions));
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Handles the start of a 2D loading operation.
|
|
304
|
-
* Updates loading state, sets attributes, and dispatches a "drawing-loading" event.
|
|
305
|
-
* @private
|
|
306
|
-
* @returns {void}
|
|
307
|
-
*/
|
|
308
|
-
#on2DLoading() {
|
|
309
|
-
this.#isLoaded = false;
|
|
310
|
-
this.#isLoading = true;
|
|
311
|
-
|
|
312
|
-
this.removeAttribute("loaded-2d");
|
|
313
|
-
this.setAttribute("loading-2d", "");
|
|
314
|
-
|
|
315
|
-
const customEventOptions = {
|
|
316
|
-
bubbles: true,
|
|
317
|
-
cancelable: true,
|
|
318
|
-
composed: true,
|
|
319
|
-
};
|
|
320
|
-
this.dispatchEvent(new CustomEvent("drawing-loading", customEventOptions));
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Handles the completion of a 2D loading operation.
|
|
325
|
-
* Updates loading state, sets attributes, dispatches a "drawing-loaded" event, and processes the next task.
|
|
326
|
-
* @private
|
|
327
|
-
* @param {object} [detail] - Optional details to include in the event.
|
|
328
|
-
* @returns {void}
|
|
329
|
-
*/
|
|
330
|
-
#on2DLoaded(detail) {
|
|
331
|
-
this.#isLoaded = true;
|
|
332
|
-
this.#isLoading = false;
|
|
333
|
-
|
|
334
|
-
this.removeAttribute("loading-2d");
|
|
335
|
-
this.setAttribute("loaded-2d", "");
|
|
336
|
-
|
|
337
|
-
const customEventOptions = {
|
|
338
|
-
bubbles: true,
|
|
339
|
-
cancelable: true,
|
|
340
|
-
composed: true,
|
|
341
|
-
};
|
|
342
|
-
if (detail) {
|
|
343
|
-
customEventOptions.detail = detail;
|
|
344
|
-
}
|
|
345
|
-
this.dispatchEvent(new CustomEvent("drawing-loaded", customEventOptions));
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* Handles the "drawing-zoom-changed" event from the 2D viewer component.
|
|
350
|
-
* Dispatches a custom "drawing-zoom-changed" event from the PrefViewer element, forwarding the event detail to external listeners.
|
|
351
|
-
* @private
|
|
352
|
-
* @param {CustomEvent} event - The original zoom change event from the 2D viewer.
|
|
353
|
-
* @returns {void}
|
|
354
|
-
*/
|
|
355
|
-
#on2DZoomChanged(event) {
|
|
356
|
-
event.stopPropagation();
|
|
357
|
-
event.preventDefault();
|
|
358
|
-
const customEventOptions = {
|
|
359
|
-
bubbles: true,
|
|
360
|
-
cancelable: true,
|
|
361
|
-
composed: true,
|
|
362
|
-
detail: event.detail,
|
|
363
|
-
};
|
|
364
|
-
this.dispatchEvent(new CustomEvent("drawing-zoom-changed", customEventOptions));
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Processes a configuration object by loading it into the 3D component.
|
|
369
|
-
* Dispatches loading events and processes the next task when finished.
|
|
370
|
-
* @private
|
|
371
|
-
* @param {object} config - The configuration object to process.
|
|
372
|
-
* @returns {void}
|
|
373
|
-
*/
|
|
374
|
-
#processConfig(config) {
|
|
375
|
-
if (!this.#component3D) {
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
this.#on3DLoading();
|
|
380
|
-
this.#component3D.load(config).then((detail) => {
|
|
381
|
-
this.#on3DLoaded(detail);
|
|
382
|
-
this.#processNextTask();
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* Processes a drawing object by loading it into the 2D component.
|
|
388
|
-
* Processes the next task when finished.
|
|
389
|
-
* @private
|
|
390
|
-
* @param {object} drawing - The drawing object to process.
|
|
391
|
-
* @returns {void}
|
|
392
|
-
*/
|
|
393
|
-
#processDrawing(drawing) {
|
|
394
|
-
if (!this.#component2D) {
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
this.#on2DLoading();
|
|
399
|
-
this.#component2D.load(drawing).then((detail) => {
|
|
400
|
-
this.#on2DLoaded(detail);
|
|
401
|
-
this.#processNextTask();
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Processes an environment (scene) object by wrapping it in a config and loading it.
|
|
407
|
-
* @private
|
|
408
|
-
* @param {object} environment - The environment/scene object to process.
|
|
409
|
-
* @returns {void}
|
|
410
|
-
*/
|
|
411
|
-
#processEnvironment(environment) {
|
|
412
|
-
const config = {};
|
|
413
|
-
config.scene = environment;
|
|
414
|
-
this.#processConfig(config);
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* Processes a materials object by wrapping it in a config and loading it.
|
|
419
|
-
* @private
|
|
420
|
-
* @param {object} materials - The materials object to process.
|
|
421
|
-
* @returns {void}
|
|
422
|
-
*/
|
|
423
|
-
#processMaterials(materials) {
|
|
424
|
-
const config = {};
|
|
425
|
-
config.materials = materials;
|
|
426
|
-
this.#processConfig(config);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* Processes a model object by wrapping it in a config and loading it.
|
|
431
|
-
* @private
|
|
432
|
-
* @param {object} model - The model object to process.
|
|
433
|
-
* @returns {void}
|
|
434
|
-
*/
|
|
435
|
-
#processModel(model) {
|
|
436
|
-
const config = {};
|
|
437
|
-
config.model = model;
|
|
438
|
-
this.#processConfig(config);
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Processes viewer options by loading them into the 3D component.
|
|
443
|
-
* Dispatches loading events and processes the next task.
|
|
444
|
-
* @private
|
|
445
|
-
* @param {object} options - The options object to process.
|
|
446
|
-
* @returns {void}
|
|
447
|
-
*/
|
|
448
|
-
#processOptions(options) {
|
|
449
|
-
if (!this.#component3D) {
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
this.#on3DLoading();
|
|
454
|
-
const detail = this.#component3D.setOptions(options);
|
|
455
|
-
this.#on3DLoaded(detail);
|
|
456
|
-
this.#processNextTask();
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* Processes visibility configuration for the model and scene.
|
|
461
|
-
* Shows or hides the model and/or scene based on the config, then processes the next task.
|
|
462
|
-
* @private
|
|
463
|
-
* @param {object} config - The visibility configuration object.
|
|
464
|
-
* @returns {void}
|
|
465
|
-
*/
|
|
466
|
-
#processVisibility(config) {
|
|
467
|
-
if (!this.#component3D) {
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
const showModel = config.model?.visible;
|
|
471
|
-
const showScene = config.scene?.visible;
|
|
472
|
-
if (showModel !== undefined) {
|
|
473
|
-
showModel ? this.#component3D.showModel() : this.#component3D.hideModel();
|
|
474
|
-
}
|
|
475
|
-
if (showScene !== undefined) {
|
|
476
|
-
showScene ? this.#component3D.showEnvironment() : this.#component3D.hideEnvironment();
|
|
477
|
-
}
|
|
478
|
-
this.#processNextTask();
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* ---------------------------
|
|
483
|
-
* Public methods
|
|
484
|
-
* ---------------------------
|
|
485
|
-
*/
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Sets the viewer mode to "2d" or "3d" and updates component visibility accordingly.
|
|
489
|
-
* @public
|
|
490
|
-
* @param {string} [mode=this.#mode] - The mode to set ("2d" or "3d").
|
|
491
|
-
* @returns {void}
|
|
492
|
-
*/
|
|
493
|
-
setMode(mode = this.#mode) {
|
|
494
|
-
if (mode !== "2d" && mode !== "3d") {
|
|
495
|
-
console.warn(`PrefViewer: invalid mode "${mode}". Allowed modes are "2d" and "3d".`);
|
|
496
|
-
mode = this.#mode;
|
|
497
|
-
}
|
|
498
|
-
this.#mode = mode;
|
|
499
|
-
if (mode === "2d") {
|
|
500
|
-
this.#component3D?.hide();
|
|
501
|
-
this.#component2D?.show();
|
|
502
|
-
} else {
|
|
503
|
-
this.#component3D?.show();
|
|
504
|
-
this.#component2D?.hide();
|
|
505
|
-
}
|
|
506
|
-
if (this.getAttribute("mode") !== mode) {
|
|
507
|
-
this.setAttribute("mode", mode);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* Loads a configuration object or JSON string and adds it to the task queue.
|
|
513
|
-
* If the config contains a drawing, adds a drawing task as well.
|
|
514
|
-
* @public
|
|
515
|
-
* @param {object|string} config - Configuration object or JSON string.
|
|
516
|
-
* @returns {boolean|void} Returns false if config is invalid; otherwise void.
|
|
517
|
-
*/
|
|
518
|
-
loadConfig(config) {
|
|
519
|
-
config = typeof config === "string" ? JSON.parse(config) : config;
|
|
520
|
-
if (!config) {
|
|
521
|
-
return false;
|
|
522
|
-
}
|
|
523
|
-
if (config.drawing) {
|
|
524
|
-
this.#addTaskToQueue(config.drawing, "drawing");
|
|
525
|
-
}
|
|
526
|
-
this.#addTaskToQueue(config, "config");
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Loads a model object or JSON string and adds it to the task queue.
|
|
531
|
-
* @public
|
|
532
|
-
* @param {object|string} model - Model object or JSON string.
|
|
533
|
-
* @returns {boolean|void} Returns false if model is invalid; otherwise void.
|
|
534
|
-
*/
|
|
535
|
-
loadModel(model) {
|
|
536
|
-
model = typeof model === "string" ? JSON.parse(model) : model;
|
|
537
|
-
if (!model) {
|
|
538
|
-
return false;
|
|
539
|
-
}
|
|
540
|
-
this.#addTaskToQueue(model, "model");
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* Loads a scene/environment object or JSON string and adds it to the task queue.
|
|
545
|
-
* @public
|
|
546
|
-
* @param {object|string} scene - Scene object or JSON string.
|
|
547
|
-
* @returns {boolean|void} Returns false if scene is invalid; otherwise void.
|
|
548
|
-
*/
|
|
549
|
-
loadScene(scene) {
|
|
550
|
-
scene = typeof scene === "string" ? JSON.parse(scene) : scene;
|
|
551
|
-
if (!scene) {
|
|
552
|
-
return false;
|
|
553
|
-
}
|
|
554
|
-
this.#addTaskToQueue(scene, "environment");
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
/**
|
|
558
|
-
* Loads materials object or JSON string and adds it to the task queue.
|
|
559
|
-
* @public
|
|
560
|
-
* @param {object|string} materials - Materials object or JSON string.
|
|
561
|
-
* @returns {boolean|void} Returns false if materials are invalid; otherwise void.
|
|
562
|
-
*/
|
|
563
|
-
loadMaterials(materials) {
|
|
564
|
-
materials = typeof materials === "string" ? JSON.parse(materials) : materials;
|
|
565
|
-
if (!materials) {
|
|
566
|
-
return false;
|
|
567
|
-
}
|
|
568
|
-
this.#addTaskToQueue(materials, "materials");
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
* Loads a drawing object or JSON string and adds it to the task queue.
|
|
573
|
-
* @public
|
|
574
|
-
* @param {object|string} drawing - Drawing object or JSON string.
|
|
575
|
-
* @returns {boolean|void} Returns false if drawing is invalid; otherwise void.
|
|
576
|
-
*/
|
|
577
|
-
loadDrawing(drawing) {
|
|
578
|
-
drawing = typeof drawing === "string" ? JSON.parse(drawing) : drawing;
|
|
579
|
-
if (!drawing) {
|
|
580
|
-
return false;
|
|
581
|
-
}
|
|
582
|
-
this.#addTaskToQueue(drawing, "drawing");
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
/**
|
|
586
|
-
* Sets viewer options from an object or JSON string and adds them to the task queue.
|
|
587
|
-
* @public
|
|
588
|
-
* @param {object|string} options - Options object or JSON string.
|
|
589
|
-
* @returns {boolean|void} Returns false if options are invalid; otherwise void.
|
|
590
|
-
*/
|
|
591
|
-
setOptions(options) {
|
|
592
|
-
options = typeof options === "string" ? JSON.parse(options) : options;
|
|
593
|
-
if (!options) {
|
|
594
|
-
return false;
|
|
595
|
-
}
|
|
596
|
-
this.#addTaskToQueue(options, "options");
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
/**
|
|
600
|
-
* Shows the 3D model by setting its visibility to true.
|
|
601
|
-
* Adds a visibility task to the queue for processing.
|
|
602
|
-
* @public
|
|
603
|
-
* @returns {void}
|
|
604
|
-
*/
|
|
605
|
-
showModel() {
|
|
606
|
-
const config = { model: { visible: true } };
|
|
607
|
-
this.#addTaskToQueue(config, "visibility");
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
/**
|
|
611
|
-
* Hides the 3D model by setting its visibility to false.
|
|
612
|
-
* Adds a visibility task to the queue for processing.
|
|
613
|
-
* @public
|
|
614
|
-
* @returns {void}
|
|
615
|
-
*/
|
|
616
|
-
hideModel() {
|
|
617
|
-
const config = { model: { visible: false } };
|
|
618
|
-
this.#addTaskToQueue(config, "visibility");
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
/**
|
|
622
|
-
* Shows the scene/environment by setting its visibility to true.
|
|
623
|
-
* Adds a visibility task to the queue for processing.
|
|
624
|
-
* @public
|
|
625
|
-
* @returns {void}
|
|
626
|
-
*/
|
|
627
|
-
showScene() {
|
|
628
|
-
const config = { scene: { visible: true } };
|
|
629
|
-
this.#addTaskToQueue(config, "visibility");
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
/**
|
|
633
|
-
* Hides the scene/environment by setting its visibility to false.
|
|
634
|
-
* Adds a visibility task to the queue for processing.
|
|
635
|
-
* @public
|
|
636
|
-
* @returns {void}
|
|
637
|
-
*/
|
|
638
|
-
hideScene() {
|
|
639
|
-
const config = { scene: { visible: false } };
|
|
640
|
-
this.#addTaskToQueue(config, "visibility");
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
/**
|
|
644
|
-
* Centers the 2D drawing view in the viewer.
|
|
645
|
-
* @public
|
|
646
|
-
* @returns {void}
|
|
647
|
-
* @description
|
|
648
|
-
* Only works when the viewer is in 2D mode. Pending implementation for 3D mode when active camera is not blocked.
|
|
649
|
-
*/
|
|
650
|
-
zoomCenter() {
|
|
651
|
-
if (!this.#component2D || this.#mode !== "2d") {
|
|
652
|
-
return;
|
|
653
|
-
}
|
|
654
|
-
this.#component2D.zoomCenter();
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
/**
|
|
658
|
-
* Zooms the 2D drawing to fit all content within the viewer.
|
|
659
|
-
* @public
|
|
660
|
-
* @returns {void}
|
|
661
|
-
* @description
|
|
662
|
-
* Only works when the viewer is in 2D mode. Pending implementation for 3D mode when active camera is not blocked.
|
|
663
|
-
*/
|
|
664
|
-
zoomExtentsAll() {
|
|
665
|
-
if (!this.#component2D || this.#mode !== "2d") {
|
|
666
|
-
return;
|
|
667
|
-
}
|
|
668
|
-
this.#component2D.zoomExtentsAll();
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
/**
|
|
672
|
-
* Zooms in on the 2D drawing.
|
|
673
|
-
* @public
|
|
674
|
-
* @returns {void}
|
|
675
|
-
* @description
|
|
676
|
-
* Only works when the viewer is in 2D mode. Pending implementation for 3D mode when active camera is not blocked.
|
|
677
|
-
*/
|
|
678
|
-
zoomIn() {
|
|
679
|
-
if (!this.#component2D || this.#mode !== "2d") {
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
this.#component2D.zoomIn();
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
/**
|
|
686
|
-
* Zooms out of the 2D drawing.
|
|
687
|
-
* @public
|
|
688
|
-
* @returns {void}
|
|
689
|
-
* @description
|
|
690
|
-
* Only works when the viewer is in 2D mode. Pending implementation for 3D mode when active camera is not blocked.
|
|
691
|
-
*/
|
|
692
|
-
zoomOut() {
|
|
693
|
-
if (!this.#component2D || this.#mode !== "2d") {
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
this.#component2D.zoomOut();
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
/**
|
|
700
|
-
* Initiates download of the current 3D model in GLB format.
|
|
701
|
-
* @public
|
|
702
|
-
* @returns {void}
|
|
703
|
-
*/
|
|
704
|
-
downloadModelGLB() {
|
|
705
|
-
if (!this.#component3D) {
|
|
706
|
-
return;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
this.#component3D.downloadModelGLB();
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
/**
|
|
713
|
-
* Initiates download of the current 3D model in GLTF format.
|
|
714
|
-
* @public
|
|
715
|
-
* @returns {void}
|
|
716
|
-
*/
|
|
717
|
-
downloadModelGLTF() {
|
|
718
|
-
if (!this.#component3D) {
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
this.#component3D.downloadModelGLTF();
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
/**
|
|
726
|
-
* Initiates download of the current 3D model in USDZ format.
|
|
727
|
-
* @public
|
|
728
|
-
* @returns {void}
|
|
729
|
-
*/
|
|
730
|
-
downloadModelUSDZ() {
|
|
731
|
-
if (!this.#component3D) {
|
|
732
|
-
return;
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
this.#component3D.downloadModelUSDZ();
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
/**
|
|
739
|
-
* Initiates download of the current complete scene (3D model and environment) in GLB format.
|
|
740
|
-
* @public
|
|
741
|
-
* @returns {void}
|
|
742
|
-
*/
|
|
743
|
-
downloadModelAndSceneGLB() {
|
|
744
|
-
if (!this.#component3D) {
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
this.#component3D.downloadModelAndSceneGLB();
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
/**
|
|
752
|
-
* Initiates download of the current complete scene (3D model and environment) in GLTF format.
|
|
753
|
-
* @public
|
|
754
|
-
* @returns {void}
|
|
755
|
-
*/
|
|
756
|
-
downloadModelAndSceneGLTF() {
|
|
757
|
-
if (!this.#component3D) {
|
|
758
|
-
return;
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
this.#component3D.downloadModelAndSceneGLTF();
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
/**
|
|
765
|
-
* Initiates download of the current complete scene (3D model and environment) in USDZ format.
|
|
766
|
-
* @public
|
|
767
|
-
* @returns {void}
|
|
768
|
-
*/
|
|
769
|
-
downloadModelAndSceneUSDZ() {
|
|
770
|
-
if (!this.#component3D) {
|
|
771
|
-
return;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
this.#component3D.downloadModelAndSceneUSDZ();
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
/**
|
|
778
|
-
* Initiates download of the current 3D environment in GLB format.
|
|
779
|
-
* @public
|
|
780
|
-
* @returns {void}
|
|
781
|
-
*/
|
|
782
|
-
downloadSceneGLB() {
|
|
783
|
-
if (!this.#component3D) {
|
|
784
|
-
return;
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
this.#component3D.downloadSceneGLB();
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
/**
|
|
791
|
-
* Initiates download of the current 3D environment in GLTF format.
|
|
792
|
-
* @public
|
|
793
|
-
* @returns {void}
|
|
794
|
-
*/
|
|
795
|
-
downloadSceneGLTF() {
|
|
796
|
-
if (!this.#component3D) {
|
|
797
|
-
return;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
this.#component3D.downloadSceneGLTF();
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
/**
|
|
804
|
-
* Initiates download of the current 3D environment in USDZ format.
|
|
805
|
-
* @public
|
|
806
|
-
* @returns {void}
|
|
807
|
-
*/
|
|
808
|
-
downloadSceneUSDZ() {
|
|
809
|
-
if (!this.#component3D) {
|
|
810
|
-
return;
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
this.#component3D.downloadSceneUSDZ();
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
/**
|
|
817
|
-
* ---------------------------
|
|
818
|
-
* Public properties
|
|
819
|
-
* ---------------------------
|
|
820
|
-
*/
|
|
821
|
-
|
|
822
|
-
/**
|
|
823
|
-
* Indicates whether the viewer has been initialized.
|
|
824
|
-
* @public
|
|
825
|
-
* @returns {boolean} True if initialized; otherwise, false.
|
|
826
|
-
*/
|
|
827
|
-
get isInitialized() {
|
|
828
|
-
return this.#isInitialized;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
/**
|
|
832
|
-
* Indicates whether the viewer has finished loading.
|
|
833
|
-
* @public
|
|
834
|
-
* @returns {boolean} True if loaded; otherwise, false.
|
|
835
|
-
*/
|
|
836
|
-
get isLoaded() {
|
|
837
|
-
return this.#isLoaded;
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
/**
|
|
841
|
-
* Indicates whether the viewer is currently loading.
|
|
842
|
-
* @public
|
|
843
|
-
* @returns {boolean} True if loading; otherwise, false.
|
|
844
|
-
*/
|
|
845
|
-
get isLoading() {
|
|
846
|
-
return this.#isLoading;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
/**
|
|
850
|
-
* Indicates whether the viewer is currently in 2D mode.
|
|
851
|
-
* @public
|
|
852
|
-
* @returns {boolean} True if the viewer is in 2D mode; otherwise, false.
|
|
853
|
-
*/
|
|
854
|
-
get isMode2D() {
|
|
855
|
-
return this.#mode === "2d";
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
/**
|
|
859
|
-
* Indicates whether the viewer is currently in 3D mode.
|
|
860
|
-
* @public
|
|
861
|
-
* @returns {boolean} True if the viewer is in 3D mode; otherwise, false.
|
|
862
|
-
*/
|
|
863
|
-
get isMode3D() {
|
|
864
|
-
return this.#mode === "3d";
|
|
865
|
-
}
|
|
866
|
-
}
|
|
1
|
+
// Imports all main PrefViewer components (2D, 3D, dialog, and root).
|
|
2
|
+
import PrefViewer from "./pref-viewer.js";
|
|
3
|
+
import PrefViewer2D from "./pref-viewer-2d.js";
|
|
4
|
+
import PrefViewer3D from "./pref-viewer-3d.js";
|
|
5
|
+
import PrefViewerDialog from "./pref-viewer-dialog.js";
|
|
867
6
|
|
|
7
|
+
// Defines custom elements for use as HTML tags in the application.
|
|
868
8
|
customElements.define("pref-viewer-2d", PrefViewer2D);
|
|
869
9
|
customElements.define("pref-viewer-3d", PrefViewer3D);
|
|
870
10
|
customElements.define("pref-viewer-dialog", PrefViewerDialog);
|
|
871
11
|
customElements.define("pref-viewer", PrefViewer);
|
|
12
|
+
|
|
13
|
+
// Exposes selected PrefViewer classes globally for external JavaScript use.
|
|
14
|
+
import BabylonJSAnimationController from "./babylonjs-animation-controller.js";
|
|
15
|
+
const PrefViewerClasses = {
|
|
16
|
+
BabylonJSAnimationController
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
if (typeof window !== 'undefined') {
|
|
20
|
+
window.PrefViewerClasses = PrefViewerClasses;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default PrefViewerClasses;
|