Vorschau: der Abspielen-Knopf tat beim ersten Klick nichts

animAbspielen rechnete performance.now() - ANIM_T[i] * dauer, damit die
Vorschau dort weiterlaeuft, wo der Regler steht. ANIM_T[i] ist aber undefined,
solange der Regler nie bewegt wurde: daraus wird NaN, der Fortschritt wird
NaN, und animT() liefert wegen seines eigenen "|| 0" brav wieder 0. Die
Vorschau stand still, ohne dass in der Konsole etwas auftauchte.

Bemerkt wurde es nicht, weil jede Pruefung vorher animSetzen() aufgerufen
hatte, um irgendetwas zu messen -- und damit genau den Zustand herstellte, in
dem es funktioniert. Ein Pruefskript, das den Anfangszustand anfasst, prueft
ihn nicht mehr.

animSetzen weist NaN jetzt zusaetzlich mit Number.isFinite ab, damit so ein
Wert gar nicht erst in den Stand kommt. In allen sechs Projekten nachgezogen.

Der Export war davon nicht betroffen; der Weg ueber POST /anim ist noch einmal
vom Knopf bis zur fertigen Datei durchgefahren worden.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dejanandClaude Opus 5 committed 2026-08-27 16:21:46 +02:00
1 parent 9fe7b848ee
commit 7fb1c3dfcb
9 files changed
+69 -14

No files matched your search

+16 -1
View File
@@ -316,7 +316,7 @@ violett.** Im Original steht dort `bg-surface-neutral-primary` mit Rand und
---
## 6. Sechzehn Fallen aus diesem Bau
## 6. Siebzehn Fallen aus diesem Bau
**Die Listenzeile hat drei Zeilen, nicht zwei.** Der erste Anlauf setzte Titel
und Vorschau untereinander und schob Nadel und Ungelesen-Punkt rechts neben
@@ -444,6 +444,21 @@ nicht, was das Produkt heute kann. Wo eine Aussage der Website (hier:
im vorliegenden Code hat, ist das ein Grund nachzufragen und nicht, die Aussage
auf den vorhandenen Code zu biegen.
**Ein `|| 0` an der falschen Stelle verdeckt ein NaN.** Der Abspielen-Knopf tat
nichts, sobald man ihn nach dem Laden als Erstes anfasste. `animAbspielen`
rechnete `performance.now() - ANIM_T[i] * dauer`, damit die Vorschau dort
weiterläuft, wo der Regler steht — nur ist `ANIM_T[i]` undefined, solange der
Regler nie bewegt wurde. Daraus wird NaN, der Fortschritt wird NaN, und
`animT()` liefert wegen seines eigenen `|| 0` brav wieder 0: die Vorschau stand
still, ohne dass in der Konsole etwas auftauchte.
Der Fehler war vier Commits alt und wurde nicht bemerkt, weil jede Prüfung
vorher `animSetzen()` aufgerufen hatte, um irgendetwas zu messen — und damit
genau den Zustand herstellte, in dem es funktioniert. **Ein Prüfskript, das den
Anfangszustand anfasst, prüft ihn nicht mehr.** `animSetzen` weist NaN jetzt
zusätzlich mit `Number.isFinite` ab, damit ein solcher Wert gar nicht erst in
den Stand kommt.
---
## 7. Das Bewegtbild
Binary file not shown.
+8 -2
View File
@@ -3600,7 +3600,8 @@ if (location.search.indexOf("nur=anim") >= 0)
({ i, key: a.key, dauer: a.dauer || 0, titel: a.eyebrow || a.key }));
window.animSetzen = (i, t) => {
ANIM_T[i] = Math.max(0, Math.min(1, t));
// Number.isFinite faengt NaN ab, bevor es im Stand landet.
ANIM_T[i] = Number.isFinite(t) ? Math.max(0, Math.min(1, t)) : 0;
animZeichnen(i);
const s = document.querySelector('input[data-animschieber="' + i + '"]');
if (s && document.activeElement !== s) s.value = String(Math.round(ANIM_T[i] * 1000));
@@ -3620,7 +3621,12 @@ if (location.search.indexOf("nur=anim") >= 0)
if (alt === knopf) return;
}
const dauer = (ANIMS[i].dauer || 4) * 1000;
const start = performance.now() - ANIM_T[i] * dauer;
/* Weiter, wo der Regler steht -- und bei 0 anfangen, wenn er noch nie
bewegt wurde. Ohne das || 0 ist ANIM_T[i] beim ersten Klick undefined,
start wird NaN, der Fortschritt wird NaN, und animT() liefert wegen
`|| 0` brav wieder 0: die Vorschau stand still, ohne dass irgendwo ein
Fehler auftauchte. */
const start = performance.now() - (ANIM_T[i] || 0) * dauer;
knopf.textContent = "Anhalten";
const schritt = jetzt => {
window.animSetzen(i, ((jetzt - start) % dauer) / dauer);
+8 -2
View File
@@ -3230,7 +3230,8 @@ if (location.search.indexOf("nur=anim") >= 0)
({ i, key: a.key, dauer: a.dauer || 0, titel: a.eyebrow || a.key }));
window.animSetzen = (i, t) => {
ANIM_T[i] = Math.max(0, Math.min(1, t));
// Number.isFinite faengt NaN ab, bevor es im Stand landet.
ANIM_T[i] = Number.isFinite(t) ? Math.max(0, Math.min(1, t)) : 0;
animZeichnen(i);
const s = document.querySelector('input[data-animschieber="' + i + '"]');
if (s && document.activeElement !== s) s.value = String(Math.round(ANIM_T[i] * 1000));
@@ -3250,7 +3251,12 @@ if (location.search.indexOf("nur=anim") >= 0)
if (alt === knopf) return;
}
const dauer = (ANIMS[i].dauer || 4) * 1000;
const start = performance.now() - ANIM_T[i] * dauer;
/* Weiter, wo der Regler steht -- und bei 0 anfangen, wenn er noch nie
bewegt wurde. Ohne das || 0 ist ANIM_T[i] beim ersten Klick undefined,
start wird NaN, der Fortschritt wird NaN, und animT() liefert wegen
`|| 0` brav wieder 0: die Vorschau stand still, ohne dass irgendwo ein
Fehler auftauchte. */
const start = performance.now() - (ANIM_T[i] || 0) * dauer;
knopf.textContent = "Anhalten";
const schritt = jetzt => {
window.animSetzen(i, ((jetzt - start) % dauer) / dauer);
+8 -2
View File
@@ -2899,7 +2899,8 @@ if (location.search.indexOf("nur=anim") >= 0)
({ i, key: a.key, dauer: a.dauer || 0, titel: a.eyebrow || a.key }));
window.animSetzen = (i, t) => {
ANIM_T[i] = Math.max(0, Math.min(1, t));
// Number.isFinite faengt NaN ab, bevor es im Stand landet.
ANIM_T[i] = Number.isFinite(t) ? Math.max(0, Math.min(1, t)) : 0;
animZeichnen(i);
const s = document.querySelector('input[data-animschieber="' + i + '"]');
if (s && document.activeElement !== s) s.value = String(Math.round(ANIM_T[i] * 1000));
@@ -2919,7 +2920,12 @@ if (location.search.indexOf("nur=anim") >= 0)
if (alt === knopf) return;
}
const dauer = (ANIMS[i].dauer || 4) * 1000;
const start = performance.now() - ANIM_T[i] * dauer;
/* Weiter, wo der Regler steht -- und bei 0 anfangen, wenn er noch nie
bewegt wurde. Ohne das || 0 ist ANIM_T[i] beim ersten Klick undefined,
start wird NaN, der Fortschritt wird NaN, und animT() liefert wegen
`|| 0` brav wieder 0: die Vorschau stand still, ohne dass irgendwo ein
Fehler auftauchte. */
const start = performance.now() - (ANIM_T[i] || 0) * dauer;
knopf.textContent = "Anhalten";
const schritt = jetzt => {
window.animSetzen(i, ((jetzt - start) % dauer) / dauer);
+8 -2
View File
@@ -3734,7 +3734,8 @@ if (location.search.indexOf("nur=anim") >= 0)
({ i, key: a.key, dauer: a.dauer || 0, titel: a.eyebrow || a.key }));
window.animSetzen = (i, t) => {
ANIM_T[i] = Math.max(0, Math.min(1, t));
// Number.isFinite faengt NaN ab, bevor es im Stand landet.
ANIM_T[i] = Number.isFinite(t) ? Math.max(0, Math.min(1, t)) : 0;
animZeichnen(i);
const s = document.querySelector('input[data-animschieber="' + i + '"]');
if (s && document.activeElement !== s) s.value = String(Math.round(ANIM_T[i] * 1000));
@@ -3754,7 +3755,12 @@ if (location.search.indexOf("nur=anim") >= 0)
if (alt === knopf) return;
}
const dauer = (ANIMS[i].dauer || 4) * 1000;
const start = performance.now() - ANIM_T[i] * dauer;
/* Weiter, wo der Regler steht -- und bei 0 anfangen, wenn er noch nie
bewegt wurde. Ohne das || 0 ist ANIM_T[i] beim ersten Klick undefined,
start wird NaN, der Fortschritt wird NaN, und animT() liefert wegen
`|| 0` brav wieder 0: die Vorschau stand still, ohne dass irgendwo ein
Fehler auftauchte. */
const start = performance.now() - (ANIM_T[i] || 0) * dauer;
knopf.textContent = "Anhalten";
const schritt = jetzt => {
window.animSetzen(i, ((jetzt - start) % dauer) / dauer);
+8 -2
View File
@@ -3976,7 +3976,8 @@ if (location.search.indexOf("nur=anim") >= 0)
({ i, key: a.key, dauer: a.dauer || 0, titel: a.eyebrow || a.key }));
window.animSetzen = (i, t) => {
ANIM_T[i] = Math.max(0, Math.min(1, t));
// Number.isFinite faengt NaN ab, bevor es im Stand landet.
ANIM_T[i] = Number.isFinite(t) ? Math.max(0, Math.min(1, t)) : 0;
animZeichnen(i);
const s = document.querySelector('input[data-animschieber="' + i + '"]');
if (s && document.activeElement !== s) s.value = String(Math.round(ANIM_T[i] * 1000));
@@ -3996,7 +3997,12 @@ if (location.search.indexOf("nur=anim") >= 0)
if (alt === knopf) return;
}
const dauer = (ANIMS[i].dauer || 4) * 1000;
const start = performance.now() - ANIM_T[i] * dauer;
/* Weiter, wo der Regler steht -- und bei 0 anfangen, wenn er noch nie
bewegt wurde. Ohne das || 0 ist ANIM_T[i] beim ersten Klick undefined,
start wird NaN, der Fortschritt wird NaN, und animT() liefert wegen
`|| 0` brav wieder 0: die Vorschau stand still, ohne dass irgendwo ein
Fehler auftauchte. */
const start = performance.now() - (ANIM_T[i] || 0) * dauer;
knopf.textContent = "Anhalten";
const schritt = jetzt => {
window.animSetzen(i, ((jetzt - start) % dauer) / dauer);
+8 -2
View File
@@ -4463,7 +4463,8 @@ if (location.search.indexOf("nur=anim") >= 0)
({ i, key: a.key, dauer: a.dauer || 0, titel: a.eyebrow || a.key }));
window.animSetzen = (i, t) => {
ANIM_T[i] = Math.max(0, Math.min(1, t));
// Number.isFinite faengt NaN ab, bevor es im Stand landet.
ANIM_T[i] = Number.isFinite(t) ? Math.max(0, Math.min(1, t)) : 0;
animZeichnen(i);
const s = document.querySelector('input[data-animschieber="' + i + '"]');
if (s && document.activeElement !== s) s.value = String(Math.round(ANIM_T[i] * 1000));
@@ -4483,7 +4484,12 @@ if (location.search.indexOf("nur=anim") >= 0)
if (alt === knopf) return;
}
const dauer = (ANIMS[i].dauer || 4) * 1000;
const start = performance.now() - ANIM_T[i] * dauer;
/* Weiter, wo der Regler steht -- und bei 0 anfangen, wenn er noch nie
bewegt wurde. Ohne das || 0 ist ANIM_T[i] beim ersten Klick undefined,
start wird NaN, der Fortschritt wird NaN, und animT() liefert wegen
`|| 0` brav wieder 0: die Vorschau stand still, ohne dass irgendwo ein
Fehler auftauchte. */
const start = performance.now() - (ANIM_T[i] || 0) * dauer;
knopf.textContent = "Anhalten";
const schritt = jetzt => {
window.animSetzen(i, ((jetzt - start) % dauer) / dauer);
+5 -1
View File
@@ -22,7 +22,7 @@
"int": "dezent"
}
],
"current": 0,
"current": 1,
"deck": [
{
"ref": "chat",
@@ -54,6 +54,10 @@
{
"headline": {
"dy": 3
},
"vis": {
"dx": 4,
"dy": -88
}
},
{