Animation: die Leiste laesst sich zuklappen
Ein Klick auf den Kopf klappt sie zu, dann bleiben 40 px und der Canvas hat den Platz. Sie ist dafuer ein <details> mit dem Kopf als <summary> -- damit ist die ganze Zeile die Trefferflaeche und die Tastaturbedienung kommt von selbst, statt dass ein eigener Knopf eine zweite Flaeche fuer dieselbe Sache aufmacht. Ob sie offen ist, merkt sich der Browser je Projekt im localStorage und nicht der Projektstand: das ist eine Vorliebe und keine Gestaltung, in state/<projekt>.json wuerde sie bei jedem einen Diff machen. In allen sechs Projekten nachgezogen. Im Streifenmodus faellt sie weiterhin ganz weg, die Uebersicht zeigt alle sieben Rahmen unveraendert, und der Bildexport laeuft wie vorher. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
a8f79c1224
commit
82913d78b8
7 files changed
+228
-48
No files matched your search
@@ -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/<projekt>.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
|
||||
|
||||
+37
-8
@@ -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 <details> 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 =
|
||||
'<svg class="animpfeil" viewBox="0 0 24 24" fill="none" stroke="currentColor" ' +
|
||||
'stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
|
||||
'<path d="m9 18 6-6-6-6"/></svg>';
|
||||
|
||||
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/<projekt>.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 = "<b>Animation</b><span>" +
|
||||
kopf.innerHTML = ANIM_PFEIL + "<b>Animation</b><span>" +
|
||||
(liste.length
|
||||
? liste.length + (liste.length === 1 ? " Element" : " Elemente") +
|
||||
" · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport"
|
||||
|
||||
+37
-8
@@ -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 <details> 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 =
|
||||
'<svg class="animpfeil" viewBox="0 0 24 24" fill="none" stroke="currentColor" ' +
|
||||
'stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
|
||||
'<path d="m9 18 6-6-6-6"/></svg>';
|
||||
|
||||
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/<projekt>.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 = "<b>Animation</b><span>" +
|
||||
kopf.innerHTML = ANIM_PFEIL + "<b>Animation</b><span>" +
|
||||
(liste.length
|
||||
? liste.length + (liste.length === 1 ? " Element" : " Elemente") +
|
||||
" · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport"
|
||||
|
||||
+37
-8
@@ -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 <details> 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 =
|
||||
'<svg class="animpfeil" viewBox="0 0 24 24" fill="none" stroke="currentColor" ' +
|
||||
'stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
|
||||
'<path d="m9 18 6-6-6-6"/></svg>';
|
||||
|
||||
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/<projekt>.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 = "<b>Animation</b><span>" +
|
||||
kopf.innerHTML = ANIM_PFEIL + "<b>Animation</b><span>" +
|
||||
(liste.length
|
||||
? liste.length + (liste.length === 1 ? " Element" : " Elemente") +
|
||||
" · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport"
|
||||
|
||||
+37
-8
@@ -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 <details> 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 =
|
||||
'<svg class="animpfeil" viewBox="0 0 24 24" fill="none" stroke="currentColor" ' +
|
||||
'stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
|
||||
'<path d="m9 18 6-6-6-6"/></svg>';
|
||||
|
||||
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/<projekt>.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 = "<b>Animation</b><span>" +
|
||||
kopf.innerHTML = ANIM_PFEIL + "<b>Animation</b><span>" +
|
||||
(liste.length
|
||||
? liste.length + (liste.length === 1 ? " Element" : " Elemente") +
|
||||
" · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport"
|
||||
|
||||
+37
-8
@@ -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 <details> 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 =
|
||||
'<svg class="animpfeil" viewBox="0 0 24 24" fill="none" stroke="currentColor" ' +
|
||||
'stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
|
||||
'<path d="m9 18 6-6-6-6"/></svg>';
|
||||
|
||||
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/<projekt>.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 = "<b>Animation</b><span>" +
|
||||
kopf.innerHTML = ANIM_PFEIL + "<b>Animation</b><span>" +
|
||||
(liste.length
|
||||
? liste.length + (liste.length === 1 ? " Element" : " Elemente") +
|
||||
" · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport"
|
||||
|
||||
+37
-8
@@ -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 <details> 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 =
|
||||
'<svg class="animpfeil" viewBox="0 0 24 24" fill="none" stroke="currentColor" ' +
|
||||
'stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
|
||||
'<path d="m9 18 6-6-6-6"/></svg>';
|
||||
|
||||
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/<projekt>.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 = "<b>Animation</b><span>" +
|
||||
kopf.innerHTML = ANIM_PFEIL + "<b>Animation</b><span>" +
|
||||
(liste.length
|
||||
? liste.length + (liste.length === 1 ? " Element" : " Elemente") +
|
||||
" · 1080 × 1350 · 30 fps · MP4, getrennt vom Bildexport"
|
||||
|
||||
Reference in new issue
Block a user