From 34f49d6abf5c1bf26dcb73c3f214ef2a8f910028 Mon Sep 17 00:00:00 2001 From: jessikitty Date: Mon, 3 Aug 2026 14:15:48 +1000 Subject: [PATCH] =?UTF-8?q?Add=20"Import=20set=E2=80=A6"=20footprint=20pic?= =?UTF-8?q?ker=20to=20layout=20editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/admin/layout.html | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/public/admin/layout.html b/public/admin/layout.html index 1ef7bde..4096c06 100644 --- a/public/admin/layout.html +++ b/public/admin/layout.html @@ -14,6 +14,7 @@ import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { TransformControls } from 'three/addons/controls/TransformControls.js'; import { anchorWorldMatrix } from '/js/ar/pose.js'; +import { SET_FOOTPRINTS, footprintLabel, footprintToBuilding } from '/js/set-footprints.js'; import { api, requireAuth, styles, nav } from './admin.js'; document.head.insertAdjacentHTML('beforeend', ``); await requireAuth(); @@ -37,6 +49,7 @@ app.innerHTML = `${nav('layout')}
+ @@ -55,7 +68,14 @@ app.innerHTML = `${nav('layout')} purple = ghost paths: drag the spheres, cone shows walk direction
-`; + +
+

Import Hidden Side set

+

Adds a to-scale footprint (a building box) at the view centre. Drag it into place, + then set its height/yaw in the panel. Footprints in cm; not affiliated with the LEGO Group.

+
+ +
`; let scene = await api('/api/scene'); scene.anchors ||= []; scene.buildings ||= []; scene.spawns ||= []; scene.paths ||= []; @@ -274,6 +294,23 @@ document.querySelectorAll('[data-add]').forEach(b => b.onclick = () => { buildAll(); panel(); }); +// ---------- import set footprint ---------- +const setModal = document.getElementById('setModal'); +const setList = document.getElementById('setList'); +setList.innerHTML = SET_FOOTPRINTS + .map((fp, i) => ``).join(''); +document.getElementById('importSet').onclick = () => setModal.classList.add('open'); +setModal.querySelector('.close').onclick = () => setModal.classList.remove('open'); +setModal.onclick = e => { if (e.target === setModal) setModal.classList.remove('open'); }; +setList.querySelectorAll('[data-fp]').forEach(b => b.onclick = () => { + const fp = SET_FOOTPRINTS[+b.dataset.fp]; + const t = orbit.target; + scene.buildings.push(footprintToBuilding(fp, [t.x, 0, t.z])); + sel = { kind: 'building', index: scene.buildings.length - 1 }; + setModal.classList.remove('open'); + buildAll(); panel(); +}); + // ---------- property panel ---------- const side = document.getElementById('side'); function field(label, val, oncommit, opts) { @@ -340,6 +377,8 @@ function panel(rebuild = true) { h += field('height', o.size[1], v => o.size[1] = v); h += field('depth', o.size[2], v => o.size[2] = v); h += field('yaw °', o.yawDeg || 0, v => o.yawDeg = v, { step: 1 }); + if (o.setNumber) h += `

Imported footprint · Hidden Side set ${o.setNumber}. + Size is the published build; adjust height/yaw freely.

`; } else if (sel.kind === 'pathpoint') { h = `

path ${sel.index} · point ${sel.sub + 1}/${o.points.length}

`; h += textField('path id', o.id, v => o.id = v);