← Commit history

Fusion 360 viewer: load embedded textures as data URLs

John Lauer ·61aaf209d0 ·11d ago ·parent 2336ad9
1 file changed +16
fusion-360/viewer.html+16
@@ -10,6 +10,22 @@   window.process = window.process || { env: { NODE_ENV: 'production' } };   window.global = window.global || window;   addEventListener('unhandledrejection', e => console.warn(e.reason));+  // the render route forbids blob: images, and the glTF loader hands embedded textures over as blob URLs:+  // remember each Blob's bytes and give out a data: URL instead (img-src allows data:)+  (function () {+    const _Blob = window.Blob;+    function B(parts, opts) { const b = new _Blob(parts || [], opts); try { b.__parts = parts; b.__type = (opts && opts.type) || ''; } catch (e) {} return b; }+    B.prototype = _Blob.prototype; Object.setPrototypeOf(B, _Blob); window.Blob = B;+    const _create = URL.createObjectURL.bind(URL);+    URL.createObjectURL = function (o) {+      if (!o || !o.__parts) return _create(o);+      const chunks = o.__parts.map(p => typeof p === 'string' ? new TextEncoder().encode(p) : p instanceof ArrayBuffer ? new Uint8Array(p) : ArrayBuffer.isView(p) ? new Uint8Array(p.buffer, p.byteOffset, p.byteLength) : new Uint8Array(0));+      let s = ''; for (const c of chunks) for (let i = 0; i < c.length; i += 0x8000) s += String.fromCharCode.apply(null, c.subarray(i, i + 0x8000));+      return 'data:' + (o.__type || 'application/octet-stream') + ';base64,' + btoa(s);+    };+    const _revoke = URL.revokeObjectURL.bind(URL);+    URL.revokeObjectURL = u => { if (typeof u === 'string' && u.startsWith('blob:')) _revoke(u); };+  })(); </script> <style>   :root { color-scheme: dark; }