From 61cf61ac056831610446ec42c14c78af04c9198c Mon Sep 17 00:00:00 2001 From: Andrew Thomson Date: Fri, 6 Mar 2026 08:04:39 -0500 Subject: [PATCH] Feat: Hash routing for math demo deep links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add URL hash routing (#quadrance, #cross, #weierstrass, #gravity, #color, #rotors, #prime) that auto-opens the corresponding demo modal on page load. Enables external links and the native macOS app to link directly to specific demos. 🤖 Co-Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Andy🤦‍♂️ & Claude🤖 --- modules/rt-init.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/modules/rt-init.js b/modules/rt-init.js index c3a03c9..de93c57 100644 --- a/modules/rt-init.js +++ b/modules/rt-init.js @@ -804,6 +804,39 @@ function startARTexplorer( } }); + // ======================================================================== + // HASH ROUTING — auto-open demos from URL (e.g. #quadrance, #cross) + // ======================================================================== + // Enables the native macOS app (and external links) to open specific demos + // via: https://arossti.github.io/ARTexplorer/#quadrance + + const hashDemoMap = { + quadrance: "open-quadrance-demo", + cross: "open-cross-demo", + weierstrass: "open-weierstrass-demo", + gravity: "open-gravity-demo", + color: "open-color-theory-modal", + rotors: "open-rotor-demo", + prime: "open-prime-projections-demo", + }; + + function openDemoFromHash() { + const hash = window.location.hash.replace("#", "").toLowerCase(); + if (hash && hashDemoMap[hash]) { + const linkEl = document.getElementById(hashDemoMap[hash]); + if (linkEl) { + // Small delay to ensure DOM and THREE.js are fully ready + setTimeout(() => linkEl.click(), 100); + } + } + } + + // Check hash on initial page load + openDemoFromHash(); + + // Listen for hash changes (e.g. user navigates or native app opens new hash) + window.addEventListener("hashchange", openDemoFromHash); + // ======================================================================== // GUMBALL TOOL FUNCTIONALITY // ========================================================================