diff --git a/README.md b/README.md index 8ca2644..3aead7a 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,17 @@ aus dem Browser einmalig hineingeschrieben. Im Bearbeiten-Modus lassen sich Elemente ziehen, mit den Pfeiltasten pixelweise schieben (`⇧` = 10 px) und über `A−`/`A+` in der Größe ändern. +Dazu kommen im Bedienfeld: + +| Feld | Wirkung | +|---|---| +| `X` `Y` | Stelle auf der Slide, gezählt ab der Mitte, bezogen auf die obere linke Ecke | +| `Ebene` | wie `z-index` — höher liegt weiter vorn. Leer heißt Standard | +| `Element löschen` | nimmt es aus der Slide. Es taucht darunter als „… zurück" wieder auf | + +**Der Streifen ist eine durchgehende Fläche.** Jede Slide trägt das gesamte +Blatt, ein Element lässt sich also über den ganzen Post schieben und nicht nur +in die Nachbar-Slide. ### Auf der Fläche bewegen diff --git a/post1.html b/post1.html index 6035d96..4c98eaa 100644 --- a/post1.html +++ b/post1.html @@ -1753,6 +1753,22 @@ n.style[std.prop === "font-size" ? "fontSize" : "width"] = e.size ? e.size + "px" : ""; } + // Entferntes Element: aus dem Fluss nehmen, nicht nur unsichtbar machen. + n.style.display = e.weg ? "none" : ""; + /* Die Ebene wirkt nur auf positionierten Elementen. Text steht im Fluss, + deshalb kommt beim Setzen ein relative dazu -- am Layout aendert das + nichts, macht die Ebene aber erst wirksam. Ohne Wert bleibt alles, + wie es die Gestaltung vorsieht. */ + if (e.z === undefined || e.z === null || e.z === "") { + n.style.zIndex = ""; + if (n.dataset.zpos) { n.style.position = ""; delete n.dataset.zpos; } + } else { + n.style.zIndex = e.z; + if (getComputedStyle(n).position === "static") { + n.style.position = "relative"; + n.dataset.zpos = "1"; + } + } }); } @@ -1857,11 +1873,14 @@ el.innerHTML = BG_HTML; buildWaben(el.querySelector(".layer-waben"), i); - // Nur die direkten Nachbarn: weiter als eine Slide wandert in der Praxis - // nichts, und jede zusätzliche Seite kostet Renderzeit. + /* Jede Slide traegt das vollstaendige Blatt, nicht nur ihre Nachbarn. + Vorher waren es i-1 bis i+1, und ein Element liess sich damit genau eine + Slide weit schieben, danach war es abgeschnitten. Der Post soll aber eine + durchgehende Flaeche sein. Der Preis sind n mal n Seiten statt n mal + drei -- bei einem Carousel dieser Groesse nicht spuerbar. */ const sheet = document.createElement("div"); sheet.className = "sheet"; - for (let j = Math.max(0, i - 1); j <= Math.min(SLIDES.length - 1, i + 1); j++) { + for (let j = 0; j < SLIDES.length; j++) { sheet.appendChild(buildPage(j)); } el.appendChild(sheet); @@ -2899,11 +2918,24 @@ return null; } + /* Ein geloeschtes Element laesst sich nicht mehr anklicken. Ohne diese + Liste bliebe nur "Alles auf Standard" oder Rueckgaengig -- es waere also + praktisch verloren. Sie steht deshalb immer da, nicht nur im Leerzustand. */ + function verstecktHtml() { + const versteckt = Object.keys(edits[current] || {}) + .filter(k => (edits[current][k] || {}).weg); + if (!versteckt.length) return ""; + return '
Gelöscht auf dieser Slide:
' + + '
' + + versteckt.map(k => '').join("") + '
'; + } + function syncEditPanel() { const box = document.getElementById("edit-info"); if (!picked) { box.dataset.for = ""; - box.innerHTML = 'Nichts ausgewählt'; + box.innerHTML = 'Nichts ausgewählt' + verstecktHtml(); return; } const std = STANDARD[picked.key] || {}; @@ -2924,19 +2956,61 @@ : '') + '' + '' + + '' + + '' + '' + + '
' + '
' + (std.prop ? 'Standard ' + base + ' px · ' : '') + - 'Obere linke Ecke, 0 / 0 ist die Mitte der Slide
'; + 'Obere linke Ecke, 0 / 0 ist die Mitte der Slide.
' + + 'Ebene wie z-index: höher liegt weiter vorn, leer heißt Standard.' + + verstecktHtml(); } const put = (sel, v) => { const el = box.querySelector(sel); if (el && document.activeElement !== el) el.value = v; }; if (std.prop) put("#f-size", e.size || base); + put("#f-z", e.z == null ? "" : e.z); const c = centreOf(picked.slide, picked.key); if (c) { put("#f-dx", c.x); put("#f-dy", c.y); } } + document.getElementById("edit-info").addEventListener("click", ev => { + const zurueck = ev.target.closest("[data-zurueck]"); + if (zurueck) { + const k = zurueck.dataset.zurueck; + const set = (edits[current] || {})[k]; + if (set) delete set.weg; + applyEditsAll(); + document.getElementById("edit-info").dataset.for = ""; + pick(current, k); + saveState(); + setStatus(((STANDARD[k] || {}).label || k) + " ist wieder da", "ok"); + return; + } + if (!ev.target.closest("#f-weg") || !picked) return; + const i = picked.slide, key = picked.key; + if (key === "mock-2") { + // Beim zweiten Bild wirklich entfernen, nicht nur ausblenden: sonst + // stuende es weiter im Stand und im Auswahlfeld. + werteVon(i).media2 = null; + slidesNeuAufbauen(); + picked = null; + deckNeuBauen(); + show(i); + syncInhalt(); + } else { + (edits[i][key] = edits[i][key] || {}).weg = true; + applyEditsAll(); + // Ausgewaehlt lassen: dann steht "Element zurueck" gleich bereit. Der + // Aufbau muss aber erzwungen werden, sonst fehlt die Rueckhol-Liste. + document.getElementById("edit-info").dataset.for = ""; + syncEditPanel(); + } + saveState(); + setStatus("Element entfernt", "ok"); + }); + /* Eingabe wirkt sofort. Kein pick() danach: das baut das Feld neu auf und der Fokus waere weg. */ document.getElementById("edit-info").addEventListener("input", ev => { @@ -2955,6 +3029,10 @@ if (el.id === "f-dx") set.dx = (set.dx || 0) + (ziel - c.x); else set.dy = (set.dy || 0) + (ziel - c.y); } + else if (el.id === "f-z") { + if (raw === "") delete set.z; + else set.z = Math.round(n); + } // Leere Groesse heisst Standard, nicht null. else if (el.id === "f-size") { if (raw === "") delete set.size;