diff --git a/README.md b/README.md index 81ada51..ca379e9 100644 --- a/README.md +++ b/README.md @@ -367,6 +367,12 @@ Unter dem Canvas liegt in **jedem** Projekt, im selben Fenster, ein Bereich „Animation". Er zeigt jede Animation als eigenes Blatt in Vorschau, mit Zeitregler, `Abspielen` und `MP4 exportieren`. +**Ein Klick auf den Kopf klappt ihn zu**, dann bleibt eine Zeile von 40 px und +der Canvas hat den Platz. Ob er offen ist, merkt sich der Browser je Projekt +(`localStorage`) und nicht der Projektstand: es ist eine Vorliebe und keine +Gestaltung, sie hat in `state/.json` nichts verloren, wo sie bei jedem +einen Diff machen würde. + **Eine Animation ist keine Slide.** Sie steht in `ANIMS` und nicht in `SLIDES`, liegt also nicht im Streifen, taucht in der Slide-Auswahl nicht auf und wird vom Bildexport nicht angefasst. Das ist der ganze Punkt: im Carousel diff --git a/post2-alt.html b/post2-alt.html index 4882e15..09920d0 100644 --- a/post2-alt.html +++ b/post2-alt.html @@ -553,16 +553,32 @@ if (location.search.indexOf("nur=anim") >= 0) und Grund, ohne dass irgendwo ein Fehler auftauchte. */ #animleiste { flex: 0 0 auto; border-top: 1px solid #24262F; - background: #14161C; padding: 13px 20px 16px; - max-height: 42vh; overflow-y: auto; + background: #14161C; padding: 0 20px; + max-height: 46vh; overflow-y: auto; } - .animkopf { display: flex; align-items: baseline; gap: 10px; margin-bottom: 11px; } + #animleiste[open] { padding-bottom: 16px; } + + /* Der Kopf ist der Schalter. Ein eigener Knopf daneben waere eine zweite + Trefferflaeche fuer dieselbe Sache -- die ganze Zeile ist gross genug, + und ein
bringt Tastaturbedienung von selbst mit. */ + .animkopf { + display: flex; align-items: center; gap: 10px; + padding: 12px 0; cursor: pointer; user-select: none; + list-style: none; + } + .animkopf::-webkit-details-marker { display: none; } + .animkopf:hover b { color: #FFFFFF; } + .animpfeil { + flex: none; width: 13px; height: 13px; color: #6E7480; + transition: transform .16s ease; + } + #animleiste[open] .animpfeil { transform: rotate(90deg); } .animkopf b { font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: #E8EAEE; } - .animkopf span { font-size: 11.5px; color: #6E7480; } - .animreihe { display: flex; gap: 14px; flex-wrap: wrap; } + .animkopf > span { font-size: 11.5px; color: #6E7480; } + .animreihe { display: flex; gap: 14px; flex-wrap: wrap; padding-bottom: 2px; } .animkarte { display: flex; gap: 14px; align-items: stretch; border: 1px solid #2E313B; border-radius: 10px; @@ -3654,6 +3670,12 @@ if (location.search.indexOf("nur=anim") >= 0) /* Der Bereich unter dem Canvas. Er zeigt jede Animation als eigenes Blatt in Vorschau, nicht als Eintrag in einer Liste: was hier laeuft, ist dasselbe Blatt, das hinterher im Video steht. */ + const ANIM_OFFEN = "postgrid-anim-" + PROJECT; + const ANIM_PFEIL = + ''; + function animLeisteBauen() { const liste = window.ANIM_LISTE(); let leiste = document.getElementById("animleiste"); @@ -3669,14 +3691,21 @@ if (location.search.indexOf("nur=anim") >= 0) while (buehne.firstChild) flaeche.appendChild(buehne.firstChild); buehne.appendChild(flaeche); } - leiste = document.createElement("section"); + leiste = document.createElement("details"); leiste.id = "animleiste"; + /* Ob sie offen ist, ist eine Vorliebe und kein Projektstand: sie + gehoert in den Browser und nicht in state/.json, das + gepusht wird und wo sie bei jedem einen Diff machen wuerde. */ + leiste.open = localStorage.getItem(ANIM_OFFEN) !== "zu"; + leiste.addEventListener("toggle", () => { + localStorage.setItem(ANIM_OFFEN, leiste.open ? "auf" : "zu"); + }); (buehne || document.body).appendChild(leiste); } - const kopf = document.createElement("div"); + const kopf = document.createElement("summary"); kopf.className = "animkopf"; - kopf.innerHTML = "Animation" + + kopf.innerHTML = ANIM_PFEIL + "Animation" + (liste.length ? liste.length + (liste.length === 1 ? " Element" : " Elemente") + " · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport" diff --git a/post2.html b/post2.html index 47b558e..d73f858 100644 --- a/post2.html +++ b/post2.html @@ -472,16 +472,32 @@ if (location.search.indexOf("nur=anim") >= 0) und Grund, ohne dass irgendwo ein Fehler auftauchte. */ #animleiste { flex: 0 0 auto; border-top: 1px solid #24262F; - background: #14161C; padding: 13px 20px 16px; - max-height: 42vh; overflow-y: auto; + background: #14161C; padding: 0 20px; + max-height: 46vh; overflow-y: auto; } - .animkopf { display: flex; align-items: baseline; gap: 10px; margin-bottom: 11px; } + #animleiste[open] { padding-bottom: 16px; } + + /* Der Kopf ist der Schalter. Ein eigener Knopf daneben waere eine zweite + Trefferflaeche fuer dieselbe Sache -- die ganze Zeile ist gross genug, + und ein
bringt Tastaturbedienung von selbst mit. */ + .animkopf { + display: flex; align-items: center; gap: 10px; + padding: 12px 0; cursor: pointer; user-select: none; + list-style: none; + } + .animkopf::-webkit-details-marker { display: none; } + .animkopf:hover b { color: #FFFFFF; } + .animpfeil { + flex: none; width: 13px; height: 13px; color: #6E7480; + transition: transform .16s ease; + } + #animleiste[open] .animpfeil { transform: rotate(90deg); } .animkopf b { font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: #E8EAEE; } - .animkopf span { font-size: 11.5px; color: #6E7480; } - .animreihe { display: flex; gap: 14px; flex-wrap: wrap; } + .animkopf > span { font-size: 11.5px; color: #6E7480; } + .animreihe { display: flex; gap: 14px; flex-wrap: wrap; padding-bottom: 2px; } .animkarte { display: flex; gap: 14px; align-items: stretch; border: 1px solid #2E313B; border-radius: 10px; @@ -3284,6 +3300,12 @@ if (location.search.indexOf("nur=anim") >= 0) /* Der Bereich unter dem Canvas. Er zeigt jede Animation als eigenes Blatt in Vorschau, nicht als Eintrag in einer Liste: was hier laeuft, ist dasselbe Blatt, das hinterher im Video steht. */ + const ANIM_OFFEN = "postgrid-anim-" + PROJECT; + const ANIM_PFEIL = + ''; + function animLeisteBauen() { const liste = window.ANIM_LISTE(); let leiste = document.getElementById("animleiste"); @@ -3299,14 +3321,21 @@ if (location.search.indexOf("nur=anim") >= 0) while (buehne.firstChild) flaeche.appendChild(buehne.firstChild); buehne.appendChild(flaeche); } - leiste = document.createElement("section"); + leiste = document.createElement("details"); leiste.id = "animleiste"; + /* Ob sie offen ist, ist eine Vorliebe und kein Projektstand: sie + gehoert in den Browser und nicht in state/.json, das + gepusht wird und wo sie bei jedem einen Diff machen wuerde. */ + leiste.open = localStorage.getItem(ANIM_OFFEN) !== "zu"; + leiste.addEventListener("toggle", () => { + localStorage.setItem(ANIM_OFFEN, leiste.open ? "auf" : "zu"); + }); (buehne || document.body).appendChild(leiste); } - const kopf = document.createElement("div"); + const kopf = document.createElement("summary"); kopf.className = "animkopf"; - kopf.innerHTML = "Animation" + + kopf.innerHTML = ANIM_PFEIL + "Animation" + (liste.length ? liste.length + (liste.length === 1 ? " Element" : " Elemente") + " · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport" diff --git a/post3.html b/post3.html index 0e40b28..276b3b7 100644 --- a/post3.html +++ b/post3.html @@ -451,16 +451,32 @@ if (location.search.indexOf("nur=anim") >= 0) und Grund, ohne dass irgendwo ein Fehler auftauchte. */ #animleiste { flex: 0 0 auto; border-top: 1px solid #24262F; - background: #14161C; padding: 13px 20px 16px; - max-height: 42vh; overflow-y: auto; + background: #14161C; padding: 0 20px; + max-height: 46vh; overflow-y: auto; } - .animkopf { display: flex; align-items: baseline; gap: 10px; margin-bottom: 11px; } + #animleiste[open] { padding-bottom: 16px; } + + /* Der Kopf ist der Schalter. Ein eigener Knopf daneben waere eine zweite + Trefferflaeche fuer dieselbe Sache -- die ganze Zeile ist gross genug, + und ein
bringt Tastaturbedienung von selbst mit. */ + .animkopf { + display: flex; align-items: center; gap: 10px; + padding: 12px 0; cursor: pointer; user-select: none; + list-style: none; + } + .animkopf::-webkit-details-marker { display: none; } + .animkopf:hover b { color: #FFFFFF; } + .animpfeil { + flex: none; width: 13px; height: 13px; color: #6E7480; + transition: transform .16s ease; + } + #animleiste[open] .animpfeil { transform: rotate(90deg); } .animkopf b { font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: #E8EAEE; } - .animkopf span { font-size: 11.5px; color: #6E7480; } - .animreihe { display: flex; gap: 14px; flex-wrap: wrap; } + .animkopf > span { font-size: 11.5px; color: #6E7480; } + .animreihe { display: flex; gap: 14px; flex-wrap: wrap; padding-bottom: 2px; } .animkarte { display: flex; gap: 14px; align-items: stretch; border: 1px solid #2E313B; border-radius: 10px; @@ -2953,6 +2969,12 @@ if (location.search.indexOf("nur=anim") >= 0) /* Der Bereich unter dem Canvas. Er zeigt jede Animation als eigenes Blatt in Vorschau, nicht als Eintrag in einer Liste: was hier laeuft, ist dasselbe Blatt, das hinterher im Video steht. */ + const ANIM_OFFEN = "postgrid-anim-" + PROJECT; + const ANIM_PFEIL = + ''; + function animLeisteBauen() { const liste = window.ANIM_LISTE(); let leiste = document.getElementById("animleiste"); @@ -2968,14 +2990,21 @@ if (location.search.indexOf("nur=anim") >= 0) while (buehne.firstChild) flaeche.appendChild(buehne.firstChild); buehne.appendChild(flaeche); } - leiste = document.createElement("section"); + leiste = document.createElement("details"); leiste.id = "animleiste"; + /* Ob sie offen ist, ist eine Vorliebe und kein Projektstand: sie + gehoert in den Browser und nicht in state/.json, das + gepusht wird und wo sie bei jedem einen Diff machen wuerde. */ + leiste.open = localStorage.getItem(ANIM_OFFEN) !== "zu"; + leiste.addEventListener("toggle", () => { + localStorage.setItem(ANIM_OFFEN, leiste.open ? "auf" : "zu"); + }); (buehne || document.body).appendChild(leiste); } - const kopf = document.createElement("div"); + const kopf = document.createElement("summary"); kopf.className = "animkopf"; - kopf.innerHTML = "Animation" + + kopf.innerHTML = ANIM_PFEIL + "Animation" + (liste.length ? liste.length + (liste.length === 1 ? " Element" : " Elemente") + " · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport" diff --git a/post4.html b/post4.html index e66d67b..f1185df 100644 --- a/post4.html +++ b/post4.html @@ -490,16 +490,32 @@ if (location.search.indexOf("nur=anim") >= 0) und Grund, ohne dass irgendwo ein Fehler auftauchte. */ #animleiste { flex: 0 0 auto; border-top: 1px solid #24262F; - background: #14161C; padding: 13px 20px 16px; - max-height: 42vh; overflow-y: auto; + background: #14161C; padding: 0 20px; + max-height: 46vh; overflow-y: auto; } - .animkopf { display: flex; align-items: baseline; gap: 10px; margin-bottom: 11px; } + #animleiste[open] { padding-bottom: 16px; } + + /* Der Kopf ist der Schalter. Ein eigener Knopf daneben waere eine zweite + Trefferflaeche fuer dieselbe Sache -- die ganze Zeile ist gross genug, + und ein
bringt Tastaturbedienung von selbst mit. */ + .animkopf { + display: flex; align-items: center; gap: 10px; + padding: 12px 0; cursor: pointer; user-select: none; + list-style: none; + } + .animkopf::-webkit-details-marker { display: none; } + .animkopf:hover b { color: #FFFFFF; } + .animpfeil { + flex: none; width: 13px; height: 13px; color: #6E7480; + transition: transform .16s ease; + } + #animleiste[open] .animpfeil { transform: rotate(90deg); } .animkopf b { font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: #E8EAEE; } - .animkopf span { font-size: 11.5px; color: #6E7480; } - .animreihe { display: flex; gap: 14px; flex-wrap: wrap; } + .animkopf > span { font-size: 11.5px; color: #6E7480; } + .animreihe { display: flex; gap: 14px; flex-wrap: wrap; padding-bottom: 2px; } .animkarte { display: flex; gap: 14px; align-items: stretch; border: 1px solid #2E313B; border-radius: 10px; @@ -3788,6 +3804,12 @@ if (location.search.indexOf("nur=anim") >= 0) /* Der Bereich unter dem Canvas. Er zeigt jede Animation als eigenes Blatt in Vorschau, nicht als Eintrag in einer Liste: was hier laeuft, ist dasselbe Blatt, das hinterher im Video steht. */ + const ANIM_OFFEN = "postgrid-anim-" + PROJECT; + const ANIM_PFEIL = + ''; + function animLeisteBauen() { const liste = window.ANIM_LISTE(); let leiste = document.getElementById("animleiste"); @@ -3803,14 +3825,21 @@ if (location.search.indexOf("nur=anim") >= 0) while (buehne.firstChild) flaeche.appendChild(buehne.firstChild); buehne.appendChild(flaeche); } - leiste = document.createElement("section"); + leiste = document.createElement("details"); leiste.id = "animleiste"; + /* Ob sie offen ist, ist eine Vorliebe und kein Projektstand: sie + gehoert in den Browser und nicht in state/.json, das + gepusht wird und wo sie bei jedem einen Diff machen wuerde. */ + leiste.open = localStorage.getItem(ANIM_OFFEN) !== "zu"; + leiste.addEventListener("toggle", () => { + localStorage.setItem(ANIM_OFFEN, leiste.open ? "auf" : "zu"); + }); (buehne || document.body).appendChild(leiste); } - const kopf = document.createElement("div"); + const kopf = document.createElement("summary"); kopf.className = "animkopf"; - kopf.innerHTML = "Animation" + + kopf.innerHTML = ANIM_PFEIL + "Animation" + (liste.length ? liste.length + (liste.length === 1 ? " Element" : " Elemente") + " · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport" diff --git a/post5.html b/post5.html index 436b1b8..a173f45 100644 --- a/post5.html +++ b/post5.html @@ -490,16 +490,32 @@ if (location.search.indexOf("nur=anim") >= 0) und Grund, ohne dass irgendwo ein Fehler auftauchte. */ #animleiste { flex: 0 0 auto; border-top: 1px solid #24262F; - background: #14161C; padding: 13px 20px 16px; - max-height: 42vh; overflow-y: auto; + background: #14161C; padding: 0 20px; + max-height: 46vh; overflow-y: auto; } - .animkopf { display: flex; align-items: baseline; gap: 10px; margin-bottom: 11px; } + #animleiste[open] { padding-bottom: 16px; } + + /* Der Kopf ist der Schalter. Ein eigener Knopf daneben waere eine zweite + Trefferflaeche fuer dieselbe Sache -- die ganze Zeile ist gross genug, + und ein
bringt Tastaturbedienung von selbst mit. */ + .animkopf { + display: flex; align-items: center; gap: 10px; + padding: 12px 0; cursor: pointer; user-select: none; + list-style: none; + } + .animkopf::-webkit-details-marker { display: none; } + .animkopf:hover b { color: #FFFFFF; } + .animpfeil { + flex: none; width: 13px; height: 13px; color: #6E7480; + transition: transform .16s ease; + } + #animleiste[open] .animpfeil { transform: rotate(90deg); } .animkopf b { font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: #E8EAEE; } - .animkopf span { font-size: 11.5px; color: #6E7480; } - .animreihe { display: flex; gap: 14px; flex-wrap: wrap; } + .animkopf > span { font-size: 11.5px; color: #6E7480; } + .animreihe { display: flex; gap: 14px; flex-wrap: wrap; padding-bottom: 2px; } .animkarte { display: flex; gap: 14px; align-items: stretch; border: 1px solid #2E313B; border-radius: 10px; @@ -4030,6 +4046,12 @@ if (location.search.indexOf("nur=anim") >= 0) /* Der Bereich unter dem Canvas. Er zeigt jede Animation als eigenes Blatt in Vorschau, nicht als Eintrag in einer Liste: was hier laeuft, ist dasselbe Blatt, das hinterher im Video steht. */ + const ANIM_OFFEN = "postgrid-anim-" + PROJECT; + const ANIM_PFEIL = + ''; + function animLeisteBauen() { const liste = window.ANIM_LISTE(); let leiste = document.getElementById("animleiste"); @@ -4045,14 +4067,21 @@ if (location.search.indexOf("nur=anim") >= 0) while (buehne.firstChild) flaeche.appendChild(buehne.firstChild); buehne.appendChild(flaeche); } - leiste = document.createElement("section"); + leiste = document.createElement("details"); leiste.id = "animleiste"; + /* Ob sie offen ist, ist eine Vorliebe und kein Projektstand: sie + gehoert in den Browser und nicht in state/.json, das + gepusht wird und wo sie bei jedem einen Diff machen wuerde. */ + leiste.open = localStorage.getItem(ANIM_OFFEN) !== "zu"; + leiste.addEventListener("toggle", () => { + localStorage.setItem(ANIM_OFFEN, leiste.open ? "auf" : "zu"); + }); (buehne || document.body).appendChild(leiste); } - const kopf = document.createElement("div"); + const kopf = document.createElement("summary"); kopf.className = "animkopf"; - kopf.innerHTML = "Animation" + + kopf.innerHTML = ANIM_PFEIL + "Animation" + (liste.length ? liste.length + (liste.length === 1 ? " Element" : " Elemente") + " · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport" diff --git a/post6.html b/post6.html index 5d53b8b..3cf3567 100644 --- a/post6.html +++ b/post6.html @@ -494,16 +494,32 @@ if (location.search.indexOf("nur=anim") >= 0) und Grund, ohne dass irgendwo ein Fehler auftauchte. */ #animleiste { flex: 0 0 auto; border-top: 1px solid #24262F; - background: #14161C; padding: 13px 20px 16px; - max-height: 42vh; overflow-y: auto; + background: #14161C; padding: 0 20px; + max-height: 46vh; overflow-y: auto; } - .animkopf { display: flex; align-items: baseline; gap: 10px; margin-bottom: 11px; } + #animleiste[open] { padding-bottom: 16px; } + + /* Der Kopf ist der Schalter. Ein eigener Knopf daneben waere eine zweite + Trefferflaeche fuer dieselbe Sache -- die ganze Zeile ist gross genug, + und ein
bringt Tastaturbedienung von selbst mit. */ + .animkopf { + display: flex; align-items: center; gap: 10px; + padding: 12px 0; cursor: pointer; user-select: none; + list-style: none; + } + .animkopf::-webkit-details-marker { display: none; } + .animkopf:hover b { color: #FFFFFF; } + .animpfeil { + flex: none; width: 13px; height: 13px; color: #6E7480; + transition: transform .16s ease; + } + #animleiste[open] .animpfeil { transform: rotate(90deg); } .animkopf b { font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: #E8EAEE; } - .animkopf span { font-size: 11.5px; color: #6E7480; } - .animreihe { display: flex; gap: 14px; flex-wrap: wrap; } + .animkopf > span { font-size: 11.5px; color: #6E7480; } + .animreihe { display: flex; gap: 14px; flex-wrap: wrap; padding-bottom: 2px; } .animkarte { display: flex; gap: 14px; align-items: stretch; border: 1px solid #2E313B; border-radius: 10px; @@ -4549,6 +4565,12 @@ if (location.search.indexOf("nur=anim") >= 0) /* Der Bereich unter dem Canvas. Er zeigt jede Animation als eigenes Blatt in Vorschau, nicht als Eintrag in einer Liste: was hier laeuft, ist dasselbe Blatt, das hinterher im Video steht. */ + const ANIM_OFFEN = "postgrid-anim-" + PROJECT; + const ANIM_PFEIL = + ''; + function animLeisteBauen() { const liste = window.ANIM_LISTE(); let leiste = document.getElementById("animleiste"); @@ -4564,14 +4586,21 @@ if (location.search.indexOf("nur=anim") >= 0) while (buehne.firstChild) flaeche.appendChild(buehne.firstChild); buehne.appendChild(flaeche); } - leiste = document.createElement("section"); + leiste = document.createElement("details"); leiste.id = "animleiste"; + /* Ob sie offen ist, ist eine Vorliebe und kein Projektstand: sie + gehoert in den Browser und nicht in state/.json, das + gepusht wird und wo sie bei jedem einen Diff machen wuerde. */ + leiste.open = localStorage.getItem(ANIM_OFFEN) !== "zu"; + leiste.addEventListener("toggle", () => { + localStorage.setItem(ANIM_OFFEN, leiste.open ? "auf" : "zu"); + }); (buehne || document.body).appendChild(leiste); } - const kopf = document.createElement("div"); + const kopf = document.createElement("summary"); kopf.className = "animkopf"; - kopf.innerHTML = "Animation" + + kopf.innerHTML = ANIM_PFEIL + "Animation" + (liste.length ? liste.length + (liste.length === 1 ? " Element" : " Elemente") + " · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport"