← Commit history

Viewer auto-loads on scroll into view; document the sandbox rescue

John Lauer ·45f2a523da ·2mo ago ·parent 4544ff6
1 file changed +34−10
README.html+34−10
@@ -73,13 +73,7 @@ edge. Plug it into a phone charger and it lights up.</p>     <span class="play"><b>Load interactive 3D viewer</b><i>Orbit, inspect, measure, x-ray the copper. About 15 MB.</i></span>   </button> </div>-<p class="cap">The guided walkthrough starts on its own once loaded, seven steps, and the-PCB / Schematic / Parts tabs are live. <b>Known issue:</b> the 3D tab renders black inside-the wiki, because the page is served under a CSP sandbox that gives it a null origin and the-vendored Babylon bundle exposes no light classes to work around the blocked environment map.-The same bundle renders correctly when served normally, and the still above is a real capture-of it. Tracked in the findings doc in the source bundle.-<a href="https://wiki.adom.inc/adom/evan-led-nameplate/render/viewer/index.html" target="_blank">Open the viewer full screen</a>.</p>+<p class="cap">The viewer loads when it scrolls into view, about 15 MB. The guided walkthrough starts on its own, seven steps, and the PCB / Schematic / Parts tabs are live. <a href="https://wiki.adom.inc/adom/evan-led-nameplate/render/viewer/index.html" target="_blank">Open it full screen</a>.</p>  <div class="call"><b>The one idea: the letters are the components.</b> There is no display, no driver, no firmware. Each lit pixel of the bitmap is a physical@@ -204,6 +198,17 @@ lands on copper of the right net, so verify geometrically rather than by countin <li><b>Do not set <code>schX</code>/<code>schY</code> on only some parts.</b> Giving J1 explicit schematic coordinates disabled tscircuit's auto-layout for everything else and stacked all 141 symbols at the origin. Either place every part or place none.</li>+<li><b>The 3D viewer needs a sandbox rescue to render on the wiki at all.</b> The wiki+serves README and viewer content under <code>sandbox allow-scripts; default-src 'none';+img-src data: https:; media-src data: https:</code>, and three things break silently there.+The engine never starts a render loop, so nothing is ever drawn while+<code>getFps()</code> cheerfully reports 60. <code>environmentSpecular.env</code> fetches+fine but Babylon turns it into a <code>blob:</code> URL, which <code>media-src</code>+refuses, so every PBR material renders black. And <code>frameModel()</code> leaves the+camera at radius ~2500 on a 107 mm board. No console error for any of it. The viewer here+detects all three and repairs them; the guards are no-ops when it is served normally. Same+CSP is why the GLB ships its textures as <code>data:</code> URIs and why the 13 MB bundle is+reassembled from parts as an inline script rather than a blob.</li> <li><b>MP1&ndash;MP4 share one schematic symbol, and cannot be separated.</b> Every other part here has an explicit <code>schX</code>/<code>schY</code> slot, but the machine pins are emitted by <code>&lt;Molecule&gt;</code> as@@ -273,18 +278,37 @@ Designed by Adom in Fort Worth, Texas. 2026-08-20.</p>   // default frame height and everything below the 3D viewer is unreachable.   var wrap = document.getElementById('wrap');   var last = 0;+  var host = document.getElementById('viewer');   var btn = document.getElementById('viewer-load');-  if (btn) btn.addEventListener('click', function () {+  var loaded = false;+  function loadViewer() {+    if (loaded || !host) return;+    loaded = true;     var f = document.createElement('iframe');     f.src = 'https://wiki.adom.inc/adom/evan-led-nameplate/render/viewer/index.html';     f.title = 'Evan nameplate, interactive 3D';     f.setAttribute('allow', 'fullscreen');     f.addEventListener('load', post);-    var host = document.getElementById('viewer');     host.innerHTML = '';     host.appendChild(f);     post();-  });+  }+  if (btn) btn.addEventListener('click', loadViewer);+  // Auto-load once the poster scrolls into view. A click-to-load poster reads+  // as "broken" to anyone who does not realise it is a button, and a synthetic+  // click cannot reach it from outside the sandboxed frame either, so it was+  // untestable. Deferring on visibility keeps the 15 MB off first paint+  // without making the reader do anything.+  if (host && window.IntersectionObserver) {+    var io = new IntersectionObserver(function (entries) {+      for (var i = 0; i < entries.length; i++) {+        if (entries[i].isIntersecting) { io.disconnect(); loadViewer(); return; }+      }+    }, { rootMargin: '200px' });+    io.observe(host);+  } else {+    setTimeout(loadViewer, 1200);+  }   function post() {     var h = wrap.offsetHeight + 24;     if (h !== last) { last = h; parent.postMessage({ type: 'readme-height', height: h }, '*'); }