Elemente loeschen, Ebene einstellen, Streifen als eine Flaeche

Drei Sachen, die beim Arbeiten gefehlt haben.

Der Streifen war keine durchgehende Flaeche. Jede Slide zeichnete nur ihre
direkten Nachbarn mit (i-1 bis i+1), ein Element liess sich damit genau eine
Slide weit schieben und war danach abgeschnitten. Jetzt traegt jede Slide das
vollstaendige Blatt. Der Preis sind n mal n Seiten statt n mal drei -- bei
einem Carousel dieser Groesse nicht spuerbar, und der Export laeuft
unveraendert durch.

Elemente lassen sich loeschen. Sie gehen per display:none aus dem Fluss, das
zweite Bild wird dagegen wirklich entfernt, sonst stuende es weiter im Stand
und im Auswahlfeld. Ein geloeschtes Element kann man nicht mehr anklicken,
deshalb steht es im Bedienfeld als "… zurueck" bereit -- ohne das waere es
nur ueber "Alles auf Standard" oder Rueckgaengig zu holen, also praktisch
verloren.

Und jedes Element hat ein Feld "Ebene", das wie z-index wirkt. Leer heisst
Standard, damit bleibt die Gestaltung unveraendert, solange niemand etwas
setzt. Text steht im Fluss und ignoriert z-index, deshalb kommt beim Setzen
ein position:relative dazu; am Layout aendert das nichts.

Geprueft: 8 Faelle ueber das DevTools-Protokoll (Reichweite ueber zwei
Slides hinaus, Ebene setzen und wieder leeren, loeschen und zurueckholen),
dazu der volle Exportlauf und die Maus-Bedienung.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dejanandClaude Opus 5 committed 2026-08-07 18:58:29 +02:00
1 parent cbb5141d8b
commit 778aa7bab7
2 files changed
+94 -5

No files matched your search

+11
View File
@@ -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
+83 -5
View File
@@ -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 '<div class="hint" style="margin-top:10px">Gelöscht auf dieser Slide:</div>' +
'<div class="opts" style="margin-top:4px">' +
versteckt.map(k => '<button data-zurueck="' + k + '">' +
((STANDARD[k] || {}).label || k) + ' zurück</button>').join("") + '</div>';
}
function syncEditPanel() {
const box = document.getElementById("edit-info");
if (!picked) {
box.dataset.for = "";
box.innerHTML = '<span class="dim">Nichts ausgewählt</span>';
box.innerHTML = '<span class="dim">Nichts ausgewählt</span>' + verstecktHtml();
return;
}
const std = STANDARD[picked.key] || {};
@@ -2924,19 +2956,61 @@
: '') +
'<label for="f-dx">X</label><input id="f-dx" type="number" step="1">' +
'<label for="f-dy">Y</label><input id="f-dy" type="number" step="1">' +
'<label for="f-z">Ebene</label>' +
'<input id="f-z" type="number" step="1" placeholder="Standard" style="grid-column:2/5">' +
'</div>' +
'<div class="opts" style="margin-top:8px"><button id="f-weg">Element löschen</button></div>' +
'<div class="hint">' + (std.prop ? 'Standard ' + base + ' px · ' : '') +
'Obere linke Ecke, 0 / 0 ist die Mitte der Slide</div>';
'Obere linke Ecke, 0 / 0 ist die Mitte der Slide.<br>' +
'Ebene wie z-index: höher liegt weiter vorn, leer heißt Standard.</div>' +
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;