sceneview-web 1.0.0 → 1.1.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/sceneview.js +69 -31
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sceneview-web",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "One-liner 3D for the web — SceneView.modelViewer('canvas', 'model.glb'). Powered by Filament.js WASM.",
5
5
  "main": "sceneview.js",
6
6
  "author": "SceneView Tools",
package/sceneview.js CHANGED
@@ -4,19 +4,48 @@
4
4
  * One line to render a 3D model:
5
5
  * SceneView.modelViewer("canvas", "model.glb")
6
6
  *
7
- * Prerequisites: load Filament.js CDN via <script> BEFORE this file:
8
- * <script src="https://cdn.jsdelivr.net/npm/filament@1.52.3/filament.js"></script>
7
+ * No prerequisites — sceneview.js loads Filament.js CDN automatically.
8
+ * Just include one script:
9
9
  * <script src="js/sceneview.js"></script>
10
10
  *
11
11
  * Powered by Filament.js (Google's PBR renderer, WASM).
12
12
  * https://sceneview.github.io
13
13
  *
14
- * @version 2.0.0
14
+ * @version 1.1.0
15
15
  * @license MIT
16
16
  */
17
17
  (function(global) {
18
18
  'use strict';
19
19
 
20
+ var FILAMENT_CDN = 'https://cdn.jsdelivr.net/npm/filament@1.52.3/filament.js';
21
+
22
+ /**
23
+ * Load Filament.js CDN dynamically if not already present.
24
+ * Returns a Promise that resolves when the Filament global is available.
25
+ */
26
+ function _ensureFilament() {
27
+ return new Promise(function(resolve, reject) {
28
+ // Already loaded
29
+ if (typeof Filament !== 'undefined') {
30
+ resolve();
31
+ return;
32
+ }
33
+ // Check if script tag already exists but hasn't finished loading
34
+ var existing = document.querySelector('script[src*="filament"]');
35
+ if (existing) {
36
+ existing.addEventListener('load', function() { resolve(); });
37
+ existing.addEventListener('error', function() { reject(new Error('SceneView: Failed to load Filament.js from CDN')); });
38
+ return;
39
+ }
40
+ // Inject script tag
41
+ var script = document.createElement('script');
42
+ script.src = FILAMENT_CDN;
43
+ script.onload = function() { resolve(); };
44
+ script.onerror = function() { reject(new Error('SceneView: Failed to load Filament.js from CDN (' + FILAMENT_CDN + ')')); };
45
+ document.head.appendChild(script);
46
+ });
47
+ }
48
+
20
49
  /**
21
50
  * SceneView instance — wraps Filament engine, scene, camera, renderer.
22
51
  */
@@ -59,7 +88,8 @@
59
88
  }
60
89
  return;
61
90
  }
62
- // Fetch via Filament.init (handles WASM + fetch)
91
+ // Fetch via Filament.init with asset this always fires the callback
92
+ // because it needs to fetch the asset even if WASM is already loaded
63
93
  Filament.init([url], function() {
64
94
  try {
65
95
  self._showModel(url);
@@ -291,31 +321,39 @@
291
321
 
292
322
  /**
293
323
  * Create an empty SceneView on a canvas.
294
- * Filament.js must be loaded via <script> before calling this.
324
+ * Filament.js is loaded automatically from CDN if not already present.
295
325
  *
296
326
  * @param {string|HTMLCanvasElement} canvasOrId - Canvas element or its ID
297
327
  * @param {Object} [options] - Configuration options
298
328
  * @returns {Promise<SceneViewInstance>}
299
329
  */
300
330
  function create(canvasOrId, options) {
301
- return new Promise(function(resolve, reject) {
302
- if (typeof Filament === 'undefined') {
303
- reject(new Error('SceneView: Filament.js not loaded. Add <script src="https://cdn.jsdelivr.net/npm/filament@1.52.3/filament.js"></script> before sceneview.js'));
304
- return;
305
- }
306
- Filament.init([], function() {
307
- try {
308
- resolve(_createEngine(canvasOrId, options));
309
- } catch (e) {
310
- reject(e);
331
+ return _ensureFilament().then(function() {
332
+ return new Promise(function(resolve, reject) {
333
+ // If WASM is already initialized (Engine exists), skip Filament.init
334
+ if (typeof Filament.Engine !== 'undefined') {
335
+ try {
336
+ resolve(_createEngine(canvasOrId, options));
337
+ } catch (e) {
338
+ reject(e);
339
+ }
340
+ return;
311
341
  }
342
+ // First time: initialize WASM
343
+ Filament.init([], function() {
344
+ try {
345
+ resolve(_createEngine(canvasOrId, options));
346
+ } catch (e) {
347
+ reject(e);
348
+ }
349
+ });
312
350
  });
313
351
  });
314
352
  }
315
353
 
316
354
  /**
317
355
  * One-liner: create viewer and load a model.
318
- * Filament.js must be loaded via <script> before calling this.
356
+ * Filament.js is loaded automatically from CDN if not already present.
319
357
  *
320
358
  * @param {string|HTMLCanvasElement} canvasOrId
321
359
  * @param {string} modelUrl - URL to .glb/.gltf model
@@ -323,27 +361,27 @@
323
361
  * @returns {Promise<SceneViewInstance>}
324
362
  */
325
363
  function modelViewer(canvasOrId, modelUrl, options) {
326
- return new Promise(function(resolve, reject) {
327
- if (typeof Filament === 'undefined') {
328
- reject(new Error('SceneView: Filament.js not loaded. Add <script src="https://cdn.jsdelivr.net/npm/filament@1.52.3/filament.js"></script> before sceneview.js'));
329
- return;
330
- }
331
- // Pre-fetch model AND initialize WASM in one call
332
- Filament.init([modelUrl], function() {
333
- try {
334
- var instance = _createEngine(canvasOrId, options);
335
- instance._showModel(modelUrl);
336
- resolve(instance);
337
- } catch (e) {
338
- reject(e);
339
- }
364
+ return _ensureFilament().then(function() {
365
+ return new Promise(function(resolve, reject) {
366
+ // Always use Filament.init with the model URL in the assets array.
367
+ // This works whether WASM is already loaded or not, because Filament
368
+ // needs to fetch the model asset and will call back when done.
369
+ Filament.init([modelUrl], function() {
370
+ try {
371
+ var instance = _createEngine(canvasOrId, options);
372
+ instance._showModel(modelUrl);
373
+ resolve(instance);
374
+ } catch (e) {
375
+ reject(e);
376
+ }
377
+ });
340
378
  });
341
379
  });
342
380
  }
343
381
 
344
382
  // Public API
345
383
  global.SceneView = {
346
- version: '2.0.0',
384
+ version: '1.1.0',
347
385
  create: create,
348
386
  modelViewer: modelViewer
349
387
  };