From 705690eb9907a33ee57b51de0b0899df9c81947c Mon Sep 17 00:00:00 2001 From: grabowski Date: Sun, 18 Oct 2026 14:24:54 +0700 Subject: [PATCH] Fleet calculator: plant view starts from the front, drag pans at any zoom User, 18 Oct 2026: show the factory from the front at start, and make the view movable always, not only after the first zoom. - CNXIso default rotation 1 (from the south-west: office, car park and gate face the viewer) instead of 3; documented setRotation in the header. The business plan renders pin setRotation(1) already. - Drag pans at fit as well (was only when zoomed in); grab cursor at every zoom, grabbing while dragging. On touch screens the fitted view keeps vertical swipes for page scrolling (touch-action pan-y), so a horizontal drag pans; once zoomed in every direction pans, as before. --- docs/fleet-calculator.html | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/fleet-calculator.html b/docs/fleet-calculator.html index 0175609..d251ab4 100644 --- a/docs/fleet-calculator.html +++ b/docs/fleet-calculator.html @@ -293,8 +293,8 @@ html[data-theme=light] .iso-wrap { radial-gradient(1px 1px at 91% 22%, var(--iso-star) 50%, transparent 51%), linear-gradient(180deg, var(--iso-sky1), var(--iso-sky2)); } -.iso-svg { display: block; width: 100%; height: 100%; touch-action: pan-y; cursor: default; user-select: none; -webkit-user-select: none; outline: none; } -.iso-zoomed .iso-svg { cursor: grab; } +.iso-svg { display: block; width: 100%; height: 100%; touch-action: pan-y; cursor: grab; user-select: none; -webkit-user-select: none; outline: none; } +.iso-svg.iso-dragging { cursor: grabbing; } .iso-svg:focus-visible { outline: 2px solid var(--iso-accent); outline-offset: -2px; } .iso-bar { position: absolute; top: 8px; left: 8px; right: 8px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; @@ -916,6 +916,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; } * var view = CNXIso.mount(containerEl, cfg, { onPick: function (info) {} }); * view.update(cfg); // merges cfg over the current config and redraws * view.setLevel("gf" | "1f" | "roof"); // ground-floor cutaway, upper floors, roofs + * view.setRotation(0..3); // 1 (the default) shows the factory front * view.destroy(); * * Layout: the Payap scenario model (docs/site-candidates.md), the detached @@ -2569,7 +2570,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; } function mount(el, cfg, opts) { if (!el) throw new Error("CNXIso.mount: no container"); opts = opts || {}; - var st = { raw: Object.assign({}, cfg || {}), cfg: norm(cfg), level: levelOf(opts.level || opts.mode, "roof"), rot: opts.rotation === undefined ? 3 : ((opts.rotation | 0) % 4 + 4) % 4, sel: null, uid: ++UID }; + var st = { raw: Object.assign({}, cfg || {}), cfg: norm(cfg), level: levelOf(opts.level || opts.mode, "roof"), rot: opts.rotation === undefined ? 1 : ((opts.rotation | 0) % 4 + 4) % 4, sel: null, uid: ++UID }; var wrap = document.createElement("div"); wrap.className = "iso-wrap"; wrap.innerHTML = '
' + @@ -2708,10 +2709,10 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; } zoomClient(d / pinch.d, (a.x + b.x) / 2, (a.y + b.y) / 2); pinch.d = d; return; } if (down && !moved && Math.hypot(e.clientX - down.x, e.clientY - down.y) > 5) { - moved = true; hideTip(); + moved = true; hideTip(); svg.classList.add("iso-dragging"); try { svg.setPointerCapture(e.pointerId); } catch (er) { /* ignore */ } } - if (moved && !atFit) { panPx(dx, dy); e.preventDefault(); } + if (moved) { panPx(dx, dy); e.preventDefault(); } return; } if (e.pointerType === "mouse") { @@ -2730,7 +2731,7 @@ html[data-theme=light] .iso-svg .iso-glint { display: inline; } delete ptrs[e.pointerId]; if (npt() < 2) pinch = null; if (wasDown && !moved && e.type === "pointerup") pick(e.target, e.clientX, e.clientY); - if (npt() === 0) down = null; + if (npt() === 0) { down = null; svg.classList.remove("iso-dragging"); } } svg.addEventListener("pointerup", up); svg.addEventListener("pointercancel", up);