Importiertes Bild landet mittig auf der gewaehlten Slide
Der Import legte das Bild bisher nur ab und liess die Zuordnung in einem Auswahlfeld liegen. Auf der Slide war damit nichts zu sehen, und der Import wirkte wie ein Fehlschlag -- zu Recht, denn ohne den Weg ueber "Inhalt" war das Bild nirgends. Jetzt landet es sofort auf der gerade gewaehlten Slide, mittig, und ist gleich ausgewaehlt. Die Mitte wird gemessen statt gerechnet: das Blatt ist gepolstert und die Mockups stehen perspektivisch im Raum, ein Dreisatz ueber left und bottom laege daneben. Der Versatz wandert in die Bearbeitung, das Bild bleibt also frei verschiebbar. Ein zweites Bild gibt es dafuer jetzt auf jeder Slide, nicht nur auf Feature-Slides -- sonst waere die Zusage "landet auf der gewaehlten Slide" auf der Titel-Slide gebrochen. Geprueft ueber den echten Weg (Datei ins Feld, change ausloesen) auf einer Feature- und auf der Titel-Slide: Versatz 0/0 px in beiden Faellen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
11eaf3f3e7
commit
cbb5141d8b
1 file changed
+63
-29
+63
-29
@@ -814,8 +814,9 @@
|
||||
<summary>Eigene Bilder</summary>
|
||||
<input type="file" id="bild-datei" accept="image/png,image/jpeg,image/webp,image/gif,image/avif" multiple hidden>
|
||||
<button class="btn secondary" id="bild-waehlen" style="width:100%">Bilder importieren …</button>
|
||||
<div class="hint" id="bild-hinweis">Oder eine Datei auf eine Slide ziehen — sie wird
|
||||
dort das zweite Bild und lässt sich im Bearbeiten-Modus frei schieben.
|
||||
<div class="hint" id="bild-hinweis">Das Bild landet mittig auf der gewählten Slide.
|
||||
Auf eine andere Slide ziehen legt es dort ab. Mit <b>E</b> lässt es sich schieben
|
||||
und über <b>A−</b>/<b>A+</b> in der Größe ändern.<br>
|
||||
Die Datei landet unverändert unter <b>assets/eigene/</b> und gehört mit in den Commit.</div>
|
||||
</details>
|
||||
|
||||
@@ -1792,19 +1793,6 @@
|
||||
'<img class="laptop-shot" alt="" src="' + assets[sl.img] + '"></div>';
|
||||
page.appendChild(mock);
|
||||
|
||||
if (sl.media2) {
|
||||
const m2 = sl.media2;
|
||||
const el2 = document.createElement("div");
|
||||
el2.className = "mock mock-2";
|
||||
el2.style.cssText =
|
||||
"--mock-w:" + m2.w + "px;--mock-ar:" + m2.ar +
|
||||
";--mock-left:" + m2.left + "px;--m2-bottom:" + m2.bottom +
|
||||
"px;--m2-z:" + m2.z + ";--rot:" + (m2.rot || 0) + "deg";
|
||||
el2.innerHTML =
|
||||
'<div class="mock-inner"><img class="laptop-shot" alt="" src="' +
|
||||
assets[m2.img] + '"></div>';
|
||||
page.appendChild(el2);
|
||||
}
|
||||
|
||||
if (sl.note) {
|
||||
const nt = sl.note;
|
||||
@@ -1822,6 +1810,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Ein zweites Bild gibt es auf jeder Slide, nicht nur auf Feature-Slides:
|
||||
ein importiertes Bild soll auf der gewaehlten Slide landen, egal
|
||||
welche das ist. */
|
||||
if (sl.media2) {
|
||||
const m2 = sl.media2;
|
||||
const el2 = document.createElement("div");
|
||||
el2.className = "mock mock-2";
|
||||
el2.style.cssText =
|
||||
"--mock-w:" + m2.w + "px;--mock-ar:" + m2.ar +
|
||||
";--mock-left:" + m2.left + "px;--m2-bottom:" + m2.bottom +
|
||||
"px;--m2-z:" + m2.z + ";--rot:" + (m2.rot || 0) + "deg";
|
||||
el2.innerHTML =
|
||||
'<div class="mock-inner"><img class="laptop-shot" alt="" src="' +
|
||||
assets[m2.img] + '"></div>';
|
||||
page.appendChild(el2);
|
||||
}
|
||||
|
||||
renderPage(page, j);
|
||||
return page;
|
||||
}
|
||||
@@ -2532,19 +2537,46 @@
|
||||
});
|
||||
}
|
||||
|
||||
async function alsZweitesBild(i, pfad) {
|
||||
/* Ein Element genau auf die Mitte der Slide setzen. Gerechnet wird nicht,
|
||||
sondern gemessen: das Blatt ist gepolstert, die Mockups stehen schief im
|
||||
Raum, und ein Dreisatz ueber left und bottom laege daneben. Der Versatz
|
||||
wandert in die Bearbeitung, ist also nachtraeglich frei verschiebbar. */
|
||||
function mittigSetzen(i, key) {
|
||||
const node = deck.querySelector(
|
||||
'.page[data-j="' + i + '"] [data-edit="' + key + '"]');
|
||||
if (!node) return;
|
||||
const slide = node.closest(".slide");
|
||||
if (!slide) return;
|
||||
const sr = slide.getBoundingClientRect(), nr = node.getBoundingClientRect();
|
||||
if (!sr.width || !nr.width) return;
|
||||
const k = sr.width / 1080;
|
||||
const dx = ((nr.left + nr.width / 2) - (sr.left + sr.width / 2)) / k;
|
||||
const dy = ((nr.top + nr.height / 2) - (sr.top + sr.height / 2)) / k;
|
||||
const set = (edits[i][key] = edits[i][key] || {});
|
||||
set.dx = Math.round((set.dx || 0) - dx);
|
||||
set.dy = Math.round((set.dy || 0) - dy);
|
||||
applyEditsAll();
|
||||
}
|
||||
|
||||
async function alsZweitesBild(i, pfad, mittig) {
|
||||
const ar = await seitenverhaeltnis(pfad);
|
||||
const w = werteVon(i);
|
||||
const alt = w.media2 || SLIDES[i].media2 || {};
|
||||
const vorher = w.media2 || SLIDES[i].media2 || {};
|
||||
w.media2 = {
|
||||
img: pfad, w: alt.w || 400, ar: +ar.toFixed(4),
|
||||
left: alt.left != null ? alt.left : 500,
|
||||
bottom: alt.bottom != null ? alt.bottom : 60,
|
||||
z: alt.z || 2, rot: alt.rot || 0,
|
||||
img: pfad, w: vorher.w || 480, ar: +ar.toFixed(4),
|
||||
left: vorher.left != null ? vorher.left : 300,
|
||||
bottom: vorher.bottom != null ? vorher.bottom : 400,
|
||||
z: vorher.z || 2, rot: mittig ? 0 : (vorher.rot || 0),
|
||||
};
|
||||
slidesNeuAufbauen();
|
||||
deckNeuBauen();
|
||||
show(i);
|
||||
// Ein frisch importiertes Bild soll man sehen, nicht suchen.
|
||||
if (mittig) {
|
||||
edits[i]["mock-2"] = {};
|
||||
mittigSetzen(i, "mock-2");
|
||||
pick(i, "mock-2");
|
||||
}
|
||||
saveState();
|
||||
}
|
||||
|
||||
@@ -2561,14 +2593,16 @@
|
||||
}
|
||||
// Beim Ablegen auf einer Slide wandert das erste Bild gleich dorthin. Ueber
|
||||
// den Knopf importiert man nur; zugeordnet wird dann in den Feldern.
|
||||
if (typeof zielSlide === "number") {
|
||||
await alsZweitesBild(zielSlide, pfade[0]);
|
||||
setStatus(pfade.length + " Bild(er) importiert, erstes auf Slide " +
|
||||
(zielSlide + 1) + " gelegt", "ok");
|
||||
} else {
|
||||
syncInhalt();
|
||||
setStatus(pfade.length + " Bild(er) importiert · unter Inhalt zuweisen", "ok");
|
||||
}
|
||||
/* Ohne Ziel gilt die gewaehlte Slide. Frueher wurde nur importiert und
|
||||
die Zuordnung blieb in einem Auswahlfeld liegen -- das Bild war damit
|
||||
nirgends zu sehen und der Import wirkte wie ein Fehlschlag. */
|
||||
const ziel = typeof zielSlide === "number" ? zielSlide : current;
|
||||
await alsZweitesBild(ziel, pfade[0], true);
|
||||
syncInhalt();
|
||||
setStatus(pfade.length === 1
|
||||
? "Bild auf Slide " + (ziel + 1) + " gelegt · mit E verschieben"
|
||||
: pfade.length + " Bilder importiert, erstes auf Slide " + (ziel + 1) +
|
||||
" gelegt · Rest unter Inhalt", "ok");
|
||||
}
|
||||
|
||||
document.getElementById("bild-waehlen").addEventListener("click",
|
||||
|
||||
Reference in new issue
Block a user