@preference-sl/pref-viewer 2.1.0 → 2.1.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.
- package/package.json +1 -1
- package/src/index.js +43 -8
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
* 4. **Change models at runtime**
|
|
36
36
|
* viewer.setAttribute("model", "https://example.com/models/anotherModel.glb");
|
|
37
37
|
*
|
|
38
|
-
* -----------------------------------------------------------------------------
|
|
39
|
-
* Implementation code below
|
|
40
|
-
* -----------------------------------------------------------------------------
|
|
38
|
+
* -----------------------------------------------------------------------------
|
|
39
|
+
* Implementation code below with added console logs for debugging
|
|
40
|
+
* -----------------------------------------------------------------------------
|
|
41
41
|
*/
|
|
42
42
|
|
|
43
43
|
import {
|
|
@@ -55,9 +55,12 @@ import "@babylonjs/loaders";
|
|
|
55
55
|
class PrefViewer extends HTMLElement {
|
|
56
56
|
constructor() {
|
|
57
57
|
super();
|
|
58
|
+
console.log("PrefViewer: constructor");
|
|
58
59
|
this.attachShadow({ mode: "open" });
|
|
59
60
|
this._createCanvas();
|
|
60
61
|
this._wrapCanvas();
|
|
62
|
+
|
|
63
|
+
// Initialize properties
|
|
61
64
|
this.engine = null;
|
|
62
65
|
this.scene = null;
|
|
63
66
|
this.camera = null;
|
|
@@ -72,27 +75,36 @@ class PrefViewer extends HTMLElement {
|
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
attributeChangedCallback(name, _oldValue, newValue) {
|
|
78
|
+
console.log(`PrefViewer: attributeChangedCallback - ${name} changed to ${newValue}`);
|
|
75
79
|
if (name === "model" && newValue) {
|
|
76
80
|
this.modelUrl = newValue;
|
|
81
|
+
console.log(`PrefViewer: modelUrl set to ${this.modelUrl}`);
|
|
77
82
|
this._reloadModel();
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
connectedCallback() {
|
|
87
|
+
console.log("PrefViewer: connectedCallback");
|
|
82
88
|
// If no `model` attribute is present, use default bundled GLTF
|
|
83
89
|
if (!this.hasAttribute("model")) {
|
|
84
90
|
this.modelUrl = new URL("./models/patata.gltf", import.meta.url).href;
|
|
91
|
+
console.log(`PrefViewer: no model attribute, defaulting to ${this.modelUrl}`);
|
|
92
|
+
} else {
|
|
93
|
+
this.modelUrl = this.getAttribute("model");
|
|
94
|
+
console.log(`PrefViewer: model attribute present, using ${this.modelUrl}`);
|
|
85
95
|
}
|
|
86
96
|
this._initializeBabylon();
|
|
87
97
|
}
|
|
88
98
|
|
|
89
99
|
disconnectedCallback() {
|
|
100
|
+
console.log("PrefViewer: disconnectedCallback - disposing engine");
|
|
90
101
|
this._disposeEngine();
|
|
91
102
|
window.removeEventListener("resize", this._onWindowResize);
|
|
92
103
|
}
|
|
93
104
|
|
|
94
105
|
// ====== Private setup methods ======
|
|
95
106
|
_createCanvas() {
|
|
107
|
+
console.log("PrefViewer: _createCanvas");
|
|
96
108
|
this.canvas = document.createElement("canvas");
|
|
97
109
|
Object.assign(this.canvas.style, {
|
|
98
110
|
width: "100%",
|
|
@@ -102,6 +114,7 @@ class PrefViewer extends HTMLElement {
|
|
|
102
114
|
}
|
|
103
115
|
|
|
104
116
|
_wrapCanvas() {
|
|
117
|
+
console.log("PrefViewer: _wrapCanvas");
|
|
105
118
|
const wrapper = document.createElement("div");
|
|
106
119
|
Object.assign(wrapper.style, {
|
|
107
120
|
width: "100%",
|
|
@@ -113,48 +126,62 @@ class PrefViewer extends HTMLElement {
|
|
|
113
126
|
}
|
|
114
127
|
|
|
115
128
|
_initializeBabylon() {
|
|
129
|
+
console.log("PrefViewer: _initializeBabylon - creating engine and scene");
|
|
116
130
|
// 1) Create engine and scene
|
|
117
131
|
this.engine = new Engine(this.canvas, true, { alpha: true });
|
|
118
132
|
this.scene = new Scene(this.engine);
|
|
119
133
|
this.scene.clearColor = new Color4(1, 1, 1, 1);
|
|
120
134
|
|
|
121
135
|
// 2) Hook into Babylon’s GLTF loader so "https://..." URIs aren't prefixed with blob:
|
|
136
|
+
console.log("PrefViewer: Adding preprocessUrl hook");
|
|
122
137
|
SceneLoader.OnPluginActivatedObservable.add((plugin) => {
|
|
138
|
+
console.log(`PrefViewer: Plugin activated - ${plugin.name}`);
|
|
123
139
|
if (plugin.name === "gltf" || plugin.name === "gltf2") {
|
|
124
140
|
plugin.preprocessUrl = (url) => {
|
|
125
141
|
// Normalize backslashes to forward slashes
|
|
126
142
|
const fixed = url.replace(/\\/g, "/");
|
|
143
|
+
console.log(`PrefViewer: preprocessUrl received "${url}", normalized to "${fixed}"`);
|
|
127
144
|
// If it starts with http:// or https://, return as-is:
|
|
128
145
|
if (/^https?:\/\//i.test(fixed)) {
|
|
146
|
+
console.log(`PrefViewer: preprocessUrl returning absolute URL "${fixed}"`);
|
|
129
147
|
return fixed;
|
|
130
148
|
}
|
|
131
149
|
// Otherwise, leave it (Babylon will treat it relative to the blob)
|
|
150
|
+
console.log(`PrefViewer: preprocessUrl returning relative URL "${fixed}"`);
|
|
132
151
|
return fixed;
|
|
133
152
|
};
|
|
134
153
|
}
|
|
135
154
|
});
|
|
136
155
|
|
|
137
156
|
// 3) Create camera and lights
|
|
157
|
+
console.log("PrefViewer: _createCamera and _createLights");
|
|
138
158
|
this._createCamera();
|
|
139
159
|
this._createLights();
|
|
140
160
|
|
|
141
161
|
// 4) Hook up input/event handlers
|
|
162
|
+
console.log("PrefViewer: _setupEventListeners");
|
|
142
163
|
this._setupEventListeners();
|
|
143
164
|
|
|
144
165
|
// 5) Start render loop
|
|
166
|
+
console.log("PrefViewer: Starting render loop");
|
|
145
167
|
this.engine.runRenderLoop(() => {
|
|
146
168
|
if (this.scene) {
|
|
147
169
|
this.scene.render();
|
|
148
170
|
}
|
|
149
171
|
});
|
|
150
|
-
this._onWindowResize = () =>
|
|
172
|
+
this._onWindowResize = () => {
|
|
173
|
+
console.log("PrefViewer: Window resized - calling engine.resize()");
|
|
174
|
+
this.engine.resize();
|
|
175
|
+
};
|
|
151
176
|
window.addEventListener("resize", this._onWindowResize);
|
|
152
177
|
|
|
153
178
|
// 6) Load the initial model (if modelUrl is already set)
|
|
179
|
+
console.log("PrefViewer: _initializeBabylon calling _reloadModel");
|
|
154
180
|
this._reloadModel();
|
|
155
181
|
}
|
|
156
182
|
|
|
157
183
|
_createCamera() {
|
|
184
|
+
console.log("PrefViewer: _createCamera");
|
|
158
185
|
// ArcRotateCamera that orbits around origin
|
|
159
186
|
this.camera = new ArcRotateCamera(
|
|
160
187
|
"camera",
|
|
@@ -168,6 +195,7 @@ class PrefViewer extends HTMLElement {
|
|
|
168
195
|
}
|
|
169
196
|
|
|
170
197
|
_createLights() {
|
|
198
|
+
console.log("PrefViewer: _createLights");
|
|
171
199
|
// Simple hemispheric + directional as a starting point
|
|
172
200
|
this.hemiLight = new HemisphericLight(
|
|
173
201
|
"hemiLight",
|
|
@@ -186,6 +214,7 @@ class PrefViewer extends HTMLElement {
|
|
|
186
214
|
}
|
|
187
215
|
|
|
188
216
|
_setupEventListeners() {
|
|
217
|
+
console.log("PrefViewer: _setupEventListeners");
|
|
189
218
|
// Zoom toward point-of-interest on wheel scroll
|
|
190
219
|
this.canvas.addEventListener("wheel", (evt) => {
|
|
191
220
|
if (!this.scene || !this.camera) return;
|
|
@@ -207,7 +236,9 @@ class PrefViewer extends HTMLElement {
|
|
|
207
236
|
|
|
208
237
|
// ====== Model loading / management ======
|
|
209
238
|
async _reloadModel() {
|
|
239
|
+
console.log(`PrefViewer: _reloadModel - loading ${this.modelUrl}`);
|
|
210
240
|
if (!this.scene || !this.modelUrl) {
|
|
241
|
+
console.warn("PrefViewer: _reloadModel aborted (scene or modelUrl missing)");
|
|
211
242
|
return;
|
|
212
243
|
}
|
|
213
244
|
|
|
@@ -215,6 +246,7 @@ class PrefViewer extends HTMLElement {
|
|
|
215
246
|
this._disposePreviousMeshes();
|
|
216
247
|
|
|
217
248
|
try {
|
|
249
|
+
console.log(`PrefViewer: ImportMeshAsync("${this.modelUrl}")`);
|
|
218
250
|
const result = await SceneLoader.ImportMeshAsync(
|
|
219
251
|
null,
|
|
220
252
|
"",
|
|
@@ -223,10 +255,10 @@ class PrefViewer extends HTMLElement {
|
|
|
223
255
|
undefined,
|
|
224
256
|
".gltf"
|
|
225
257
|
);
|
|
226
|
-
|
|
258
|
+
console.log("PrefViewer: Model loaded, creating default camera/light if needed");
|
|
227
259
|
this.scene.createDefaultCameraOrLight(true, true, true);
|
|
228
260
|
|
|
229
|
-
|
|
261
|
+
console.log("PrefViewer: Dispatching model-loaded event");
|
|
230
262
|
this.dispatchEvent(
|
|
231
263
|
new CustomEvent("model-loaded", {
|
|
232
264
|
detail: {
|
|
@@ -238,8 +270,8 @@ class PrefViewer extends HTMLElement {
|
|
|
238
270
|
})
|
|
239
271
|
);
|
|
240
272
|
} catch (err) {
|
|
241
|
-
console.error("Error loading model:", err);
|
|
242
|
-
|
|
273
|
+
console.error("PrefViewer: Error loading model:", err);
|
|
274
|
+
console.log("PrefViewer: Dispatching model-error event");
|
|
243
275
|
this.dispatchEvent(
|
|
244
276
|
new CustomEvent("model-error", {
|
|
245
277
|
detail: { error: err },
|
|
@@ -251,9 +283,11 @@ class PrefViewer extends HTMLElement {
|
|
|
251
283
|
}
|
|
252
284
|
|
|
253
285
|
_disposePreviousMeshes() {
|
|
286
|
+
console.log("PrefViewer: _disposePreviousMeshes");
|
|
254
287
|
if (!this.scene) return;
|
|
255
288
|
this.scene.meshes.slice().forEach((mesh) => {
|
|
256
289
|
if (mesh.getClassName() === "Mesh") {
|
|
290
|
+
console.log(`PrefViewer: Disposing mesh ${mesh.name}`);
|
|
257
291
|
mesh.dispose();
|
|
258
292
|
}
|
|
259
293
|
});
|
|
@@ -261,6 +295,7 @@ class PrefViewer extends HTMLElement {
|
|
|
261
295
|
|
|
262
296
|
// ====== Cleanup ======
|
|
263
297
|
_disposeEngine() {
|
|
298
|
+
console.log("PrefViewer: _disposeEngine");
|
|
264
299
|
if (this.engine) {
|
|
265
300
|
this.engine.dispose();
|
|
266
301
|
this.engine = null;
|