From 79821775b00c403302382b09731cf702a947b4d7 Mon Sep 17 00:00:00 2001 From: DeeCee03 Date: Thu, 13 Aug 2026 22:08:39 +0200 Subject: [PATCH] Uebersicht: kein Zoom mehr, nur noch scrollen Zwei Zoom-Ebenen lagen uebereinander, und beide waren falsch. Aussen ein Rad-Zoom, der nur die iframes skaliert hat -- Beschriftung, Abstaende und Polster stehen ausserhalb der Transformation und blieben stehen, also standen beim Herauszoomen riesige Ueberschriften ueber winzigen Streifen. Und innen reagierte die Post-Seite im iframe weiter auf ihr eigenes Mausrad, weil sie ihren Canvas mitbringt. Jetzt: jeder Streifen wird auf die Fensterbreite eingepasst, gescrollt wird nur hoch und runter. Die iframes bekommen pointer-events: none -- die Uebersicht ist zum Ansehen da, bedient wird im Projekt selbst. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 3 +- uebersicht.html | 101 +++++++++++------------------------------------- 2 files changed, 24 insertions(+), 80 deletions(-) diff --git a/README.md b/README.md index 31c2679..7d96872 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,8 @@ nach: jedes Projekt kommt als `iframe` mit `?nur=streifen`, und in diesem Modus blendet die Post-Seite ihre Bedienoberfläche aus, zeigt den Streifen in natürlicher Größe und **speichert nichts** — drei Kacheln, die beim Schließen ihren Stand zurückschreiben, wären genau die Falle aus [`POST-2.md`](./POST-2.md) §6. -Skaliert wird außen; ziehen schiebt, das Rad zoomt, `Fit` passt ein. +Jeder Streifen ist auf die Fensterbreite eingepasst, gescrollt wird nur +hoch und runter — kein Zoom, weder außen noch im Streifen. **Post 2 gibt es zweimal, in zwei Themes.** Projekt und Theme sind zwei verschiedene Dinge: das Projekt sagt, welcher Beitrag, das Theme, wie er diff --git a/uebersicht.html b/uebersicht.html index d8065b4..f59ab99 100644 --- a/uebersicht.html +++ b/uebersicht.html @@ -50,14 +50,17 @@ .menu .liste button:hover { background: #262A34; color: #FFFFFF; } .menu .liste hr { border: 0; border-top: 1px solid #2E313B; margin: 5px 2px; } - /* Dieselbe Fläche wie im Generator: gepunkteter Grund, ziehbar, Rad zoomt. */ + /* Derselbe gepunktete Grund wie im Generator, aber ohne dessen Canvas: + hier wird nur gescrollt. */ .stage { position: absolute; inset: 34px 0 0; overflow: hidden; background-color: #101116; background-image: radial-gradient(circle, #282B35 1.6px, transparent 1.6px); background-size: 26px 26px; } - .scroller { position: absolute; inset: 0; overflow: auto; overscroll-behavior: contain; } - .scroller.panning { cursor: grabbing; } + /* Nur hoch und runter. Die Streifen sind auf die Breite eingepasst, + also gibt es waagerecht nichts zu holen. */ + .scroller { position: absolute; inset: 0; overflow-y: auto; overflow-x: hidden; + overscroll-behavior: contain; } .flaeche { width: max-content; min-width: 100%; height: max-content; min-height: 100%; padding: 54px; display: flex; flex-direction: column; gap: 46px; @@ -74,8 +77,12 @@ bleibt in Originalgröße und wird nur transformiert. Ohne den Rahmen würde das ungeskalierte iframe die Fläche aufblähen. */ .rahmen { overflow: hidden; background: #FFFFFF; border: 1px solid #2E313B; } + /* pointer-events: none -- sonst zoomt das Mausrad im Streifen die + Post-Seite darin, die ja ihren eigenen Canvas mitbringt. Die Uebersicht + ist zum Ansehen da, bedient wird im Projekt selbst. */ .rahmen iframe { display: block; border: 0; transform-origin: 0 0; background: #FFFFFF; + pointer-events: none; } .reihe.fehlt .rahmen { display: grid; place-items: center; width: 420px; height: 90px; background: #16181F; color: #6E7480; font-size: 13px; } @@ -87,13 +94,6 @@ border-top: 1px solid #23262F; } .hud p { margin: 0; font-size: 12px; color: #6E7480; letter-spacing: .04em; } - .zoom { margin-left: auto; display: flex; gap: 4px; } - .zoom button { - font: inherit; font-size: 13px; font-weight: 700; cursor: pointer; - background: #1D1F26; color: #C7CCD6; border: 1px solid #2E313B; - border-radius: 7px; padding: 6px 10px; min-width: 32px; - } - .zoom button:hover { background: #262A34; color: #FFFFFF; } @@ -118,11 +118,6 @@

Lade Streifen ...

-
- - - -
@@ -140,10 +135,12 @@ const scroller = document.getElementById("scroller"); const meta = document.getElementById("meta"); - /* Ein Streifen ist bis zu 6480 px breit. Der Maßstab ist deshalb nicht - frei, sondern immer relativ zu "passt in die Fläche" -- sonst müsste man - bei jedem Öffnen erst herauszoomen. zoom === null heißt eingepasst. */ - let zoom = null; + /* Kein Zoom. Ein Streifen ist bis zu 6480 px breit und wird immer auf die + Fensterbreite eingepasst; gescrollt wird nur hoch und runter. Ein + Zwischenstand hatte Rad-Zoom und Zoomknöpfe -- das war doppelt gemoppelt, + weil die Post-Seite im iframe ihren eigenen Canvas mitbringt, und die + Beschriftungen skalierten nicht mit, standen beim Herauszoomen also + riesig über winzigen Streifen. */ const reihen = []; function bauen() { @@ -178,22 +175,15 @@ legen(); }); - /* Beschriftung, Abstände und Polster skalieren NICHT mit -- sie stehen - außerhalb des transformierten iframes. Ein einfaches - "verfügbar / Gesamthöhe" ließ die letzte Reihe deshalb unten - hinauslaufen. Die feste Höhe muss vorher abgezogen werden. */ - const POLSTER = 54 * 2, LUECKE = 46, KOPFZEILE = 32; + // Eingepasst wird nur in die Breite, die Höhe ergibt sich und wird gescrollt. + const POLSTER = 54 * 2; function passend() { - const n = reihen.length; const breit = Math.max(...reihen.map(r => r.w), 1080); - const hoch = reihen.reduce((s, r) => s + r.h, 0); - const fest = POLSTER + (n - 1) * LUECKE + n * KOPFZEILE; - return Math.min((scroller.clientWidth - POLSTER) / breit, - Math.max(0.02, (scroller.clientHeight - fest) / hoch), 0.5); + return Math.min((scroller.clientWidth - POLSTER) / breit, 0.5); } function legen() { - const k = zoom || passend(); + const k = passend(); reihen.forEach(r => { r.ram.style.width = r.w + "px"; r.ram.style.height = r.h + "px"; @@ -201,57 +191,14 @@ r.rahmen.style.width = Math.round(r.w * k) + "px"; r.rahmen.style.height = Math.round(r.h * k) + "px"; }); - document.getElementById("zoom-fit").textContent = zoom ? Math.round(k * 100) + " %" : "Fit"; const offen = reihen.filter(r => r.da).length; meta.textContent = offen < reihen.length ? "Lade Streifen ... " + offen + " von " + reihen.length : reihen.length + " Projekte · " + reihen.map(r => Math.round(r.w / 1080) + " Slides").join(" · "); } - function zoomAuf(k, anker) { - const vor = zoom || passend(); - const ax = anker ? anker.x : scroller.clientWidth / 2; - const ay = anker ? anker.y : scroller.clientHeight / 2; - const s0 = scroller.getBoundingClientRect(); - const f0 = flaeche.getBoundingClientRect(); - const u = (s0.left + ax - f0.left) / vor; - const v = (s0.top + ay - f0.top) / vor; - zoom = Math.min(1, Math.max(0.02, k)); - legen(); - const f1 = flaeche.getBoundingClientRect(); - scroller.scrollLeft += (f1.left + u * zoom) - (s0.left + ax); - scroller.scrollTop += (f1.top + v * zoom) - (s0.top + ay); - } - - // ─── Bedienung: ziehen, Rad zoomt, Umschalt+Rad schiebt waagerecht ─────── - let zieht = null; - scroller.addEventListener("pointerdown", e => { - if (e.button !== 0 && e.button !== 1) return; - zieht = { x: e.clientX, y: e.clientY, l: scroller.scrollLeft, t: scroller.scrollTop }; - scroller.classList.add("panning"); - scroller.setPointerCapture(e.pointerId); - }); - scroller.addEventListener("pointermove", e => { - if (!zieht) return; - scroller.scrollLeft = zieht.l - (e.clientX - zieht.x); - scroller.scrollTop = zieht.t - (e.clientY - zieht.y); - }); - const losen = () => { zieht = null; scroller.classList.remove("panning"); }; - scroller.addEventListener("pointerup", losen); - scroller.addEventListener("pointercancel", losen); - - scroller.addEventListener("wheel", e => { - if (e.shiftKey) return; // waagerecht schieben - e.preventDefault(); - const r = scroller.getBoundingClientRect(); - zoomAuf((zoom || passend()) * (e.deltaY < 0 ? 1.12 : 1 / 1.12), - { x: e.clientX - r.left, y: e.clientY - r.top }); - }, { passive: false }); - - document.getElementById("zoom-in").addEventListener("click", () => zoomAuf((zoom || passend()) * 1.2)); - document.getElementById("zoom-out").addEventListener("click", () => zoomAuf((zoom || passend()) / 1.2)); - document.getElementById("zoom-fit").addEventListener("click", () => { zoom = null; legen(); }); - window.addEventListener("resize", () => { if (!zoom) legen(); }); + // Kein Ziehen, kein Rad-Zoom: die Seite scrollt wie eine gewoehnliche Seite. + window.addEventListener("resize", legen); // ─── Menü ──────────────────────────────────────────────────────────────── document.querySelectorAll(".menu").forEach(m => { @@ -269,10 +216,6 @@ if (b.dataset.gehe) { location.href = b.dataset.gehe; return; } if (b.dataset.klick === "neu") { bauen(); legen(); } }); - document.addEventListener("keydown", e => { - if (e.key === "0") { zoom = null; legen(); } - }); - bauen(); legen(); })();