Communitygithub.com

motion-video-skill · Überschrift/Effekt/Daten-Visualisierung/Er…

Erstelle Animationen und Videos mit Code: Vorspann-Effekte, Untertitel-Animationen, Daten-Visualisierungs-Effekte, UI-Demos, Erklär-Schnipsel, Endlos-GIFs – Ausgabe als mp4/webm/gif/webp. Die Pipeline stellt sicher, dass die Animation wirklich läuft und keine Zwischenzustände verloren gehen.

Was ist Effekt/Daten-Visualisierung/Er…?

Dieses Skill löst ein grundlegendes Problem: Kleine Modelle (Flash/mini/turbo) können zwar CSS und Canvas schreiben, aber die resultierenden Animationen sind oft nur ‚scheinbar‘ vorhanden – Zwischenzustände werden übersprungen, Easing-Kurven sind falsch, Schlüsselelemente erscheinen zu anderen Zeiten oder die Animation bleibt auf halbem Weg stecken. Das Modell selbst merkt es nicht, weil es die Bilder nicht sehen kann. Der Ansatz ist daher nicht ‚schreibe es schöner‘, sondern die Animation als maschinell prüfbares Artefakt zu definieren: Spezifikation vor Code (alle Zustände tabellarisch erfassen), Bilder als reine Funktion von `t` (kein `requestAnimationFrame` oder `Date.now()`), numerische Parameter ausschließlich über Helfertools (`scripts/ease.mjs`), deterministischer Renderer (gleicher Code → gleicher Frame), maschinelle Prüfung (zuerst numerisch, dann pixelbasiert) und erst danach menschliche Bewertung. Das Skill unterstützt die Arbeit mit gängigen Render-Umgebungen wie Chrome/Edge, ffmpeg und Node.js und bietet eine komplette Pipeline von der Spezifikation über die Code-Generierung, numerische Verifikation, Pixel-Audit bis zur finalen Abgabe mit Bewegungsunschärfe und Kontaktabzug. Es ist ideal für Entwickler, die hochwertige, verifizierte Animationen erstellen wollen, ohne auf große Video-Modelle oder manuelles Compositing angewiesen zu sein.

Funktioniert mit✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/IFIAnder/motion-video-skill/tree/HEAD

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

motion-video · Animationen mit Code, die maschinell prüfbar sind

Dieses Skill löst ein spezifisches Problem: Kleine Modelle (Flash/mini/turbo) können CSS und Canvas schreiben, aber die resultierenden Animationen sind oft nur „scheinbar“ vorhanden – Zwischenzustände werden übersprungen, Easing ist falsch, Schlüsselelemente erscheinen zu anderen Zeiten, und das Ende bleibt auf halbem Weg stecken. Das Modell selbst merkt es nicht, weil es keine Augen hat.

Der Ansatz ist daher nicht „schreibe es hübscher“, sondern die Animation als maschinell prüfbares Artefakt zu definieren:

  1. Spezifikation vor Code – übersetze ästhetische Urteile in tabellarische Werte.
  2. Das Bild muss eine reine Funktion von t sein – zwinge Zwischenzustände strukturell ein.
  3. Zahlen gehören zu Skripten – Bézier, Feder, Staffelung, Kontrast – alles über Tools, nicht im Kopf.
  4. Verwende einen deterministischen Renderer (Frame für Frame) – derselbe Code, derselbe Frame.
  5. Maschinelle Prüfung: zuerst numerisch, dann auf Pixelebene.
  6. Erst wenn die Maschine sagt „Struktur in Ordnung“, kommt der Mensch zur Komposition.

Lücken werden nicht durch einen Zauberspruch geschlossen, sondern durch diese sechs Schritte – sie machen „falsch“ zu „erkennbar und reparierbar“. Wo die Lücken herkommen, welche geschlossen werden können und welche nicht, siehe references/delta-vs-opus.md.


Qualität zuerst: Nur unnötige Kosten sparen, nicht die Validierung

Diese Regel steht über den eisernen Regeln. Das Ziel dieses Skills ist Opus-Level-Videos, nicht die billigsten Videos. Der Maßstab ist daher nicht, ob es schnell ist, sondern ob es besser wird.

Nur eine Art von Kosten darf gespart werden: wiederholte, ineffektive, sich gegenseitig um Ressourcen streitende. Validierungsdichte, Renderingqualität, Bildrate, Bewegungsunschärfe – diese werden nicht gespart.

Erlaubt zu sparen (Verschwendung, Sparen bringt keinen Mehrwert)

VerschwendungSparmethode
4 Chrome-Prozesse starten, die sich um CPU streitenSerielle Ausführung (schneller als parallel), render.mjs hat bereits eine Sperre eingebaut
Ein 20KB-Spezifikationsdokument pro KapitelEin vollständiges storyboard.md erstellen
Wiederholtes render --still für jeweils nur einen FrameEinmal 6–8 Zeitpunkte aufnehmen
Wiederholte Analyse desselben MaterialsEinmal analysieren, Ergebnis ins Storyboard schreiben
Frame-für-Frame-PNGs auf Platte speichern und wieder einlesenoptimizeForSpeed ist bereits aktiviert; bei großen Projekten auf image2pipe umstellen (cinema-grade.md §9)
„Aus Sicherheit“ dieselbe Sache dreimal validierenZweimal validieren (numerisch + Pixel) reicht, eine dritte Prüfung bringt keine neuen Informationen

Verboten zu sparen (Sparen bedeutet Qualitätsverlust)

Nicht sparenBegründung
Vollständiges audit, inklusive jump/flat-BearbeitungLetzte Prüfung vor der Auslieferung – Überspringen = keine Abnahme
verify --idempotentWenn die Idempotenz zerstört ist, sind alle nachfolgenden Prüfungen unglaubwürdig
rigcheck (jedes Mal, wenn ein Charakter oder eine Pose geändert wird)Skelettfehlstellungen können nur numerisch erkannt werden, nicht mit dem Auge
Bewegungsunschärfe in der finalen AusgabeDer Unterschied zwischen „mit und ohne Verschluss“ ist eine ganze Qualitätsstufe, kein schmückendes Beiwerk
60fps bei schnellen BewegungenBei 30fps ruckeln schnelle Gliedmaßen – das ist ein Defekt, keine Entscheidung
Frame-Prüfung (mehrere Zeitpunkte + lokale Vergrößerung)Ein Bild zeigt keine Probleme in der Mitte; mindestens 6 Frames + 2–3× Vergrößerung der Schlüsselbereiche
Nach der Reparatur erneut ausführen (nicht „sollte behoben sein“)Ohne erneute Ausführung ist nichts repariert

Entscheidungshilfe in einem Satz

Gesparte Wartezeit kann gespart werden; gesparte „Gelegenheit, Fehler zu entdecken“, nicht.

Dass ein Rendern 70 Minuten dauert, ist inakzeptabel, nicht weil „70 Minuten zu lang sind“, sondern weil 85% dieser 70 Minuten darauf entfallen, dass 4 Prozesse sich um CPU kloppen – die Wartezeit hat keine Qualität gebracht. Aber für eine 180°-Verschlusszeit die 4-fache Renderzeit zu investieren, bringt eine spürbare Verbesserung der Bildwirkung – das muss investiert werden.

Die richtige Reihenfolge der Beschleunigung

  1. Verschwendung zuerst eliminieren: Parallelaufrufe seriell machen, doppelte Starts vermeiden, redundante Dokumente löschen, Frames bündeln.
  2. Dann Implementierung optimieren: Screenshot-Parameter, mehrere Tabs in einem Chrome-Prozess, direkter Zugriff auf den Encoder ohne Zwischenablage.
  3. Erst zuletzt die Validierung reduzieren – und das sollte eigentlich nicht passieren; wenn doch, wurden die ersten beiden Schritte nicht gemacht.

Eiserne Regeln

Verstöße gegen eine dieser Regeln machen das Produkt unannehmbar; neu machen.

  1. Kein Code ohne Spezifikation. Zuerst die Shot- und Zeitachsen-Tabellen erstellen (STEP 1). Jedes Element in der Tabelle muss enter / active / exit als drei Zeitintervalle haben. Fehlt eines, hast du noch nicht durchdacht, wann es existiert. Aber wenn der Benutzer nur einen Satz sagt („Mach was Beeindruckendes“, „Zeig deine Fähigkeiten“, „Gib Vollgas“), darfst du nicht nachfragen – fülle die vier Slots (Motiv, Meta-Erzählung, Form, Niveau) selbst aus, schreibe sie ins storyboard.md und leg los. Siehe references/wish-mode.md.
  2. Alle Bildzustände sind reine Funktionen von seek(t). requestAnimationFrame, Date.now(), performance.now(), Math.random(), selbstinkrementierende Zähler und selbstlaufende CSS @keyframes/transition sind verboten. Derselbe Code, derselbe t, muss immer denselben Pixel erzeugen.
  3. Zahlen gehören zu Skripten, nicht ins Hirn. Bézier-Kontrollpunkte, Federparameter, Staffelung, Koordinatenberechnung, Kontrastverhältnisse, linear()-Serie – alles von ease.mjs. Solche Zahlen dürfen in deiner Antwort erst erscheinen, nachdem das Tool gelaufen ist. Siehe unten „Zahlen gehören zu Tools, Entscheidungen zu dir“.
  4. Nach jeder Änderung verify und render + audit ausführen. FAIL bedeutet nicht auslieferbar. WARN muss einzeln begründet werden („geändert“ oder „designintern, weil...“). Nicht verify überspringen und das ganze Video rendern – das kostet nur 8 Sekunden mehr, bringt aber eine dumme „Bild bewegt sich nicht“-Diagnose.
  5. Dreiteilige Abgabe: Endvideo (mp4/webm/gif) + Kontaktabzug (-sheet.png) + audit-Ergebnis.
  6. Bei ästhetischen Unsicherheiten: Optionen anbieten, nicht raten. Zwei Farbschemata, zwei Rhythmen – lass den Benutzer wählen. Das ist besser, als eine mittelmäßige Version zu liefern.
  7. Keine Materialien abwarten, selbst zeichnen. Keine Platzhalter wie „Bild hier einfügen“, „Grafik empfohlen“, „warten auf Material“. Die Renderpipeline besteht nur aus HTML/CSS/SVG/Canvas – alle visuellen Elemente müssen aus Code generiert werden. Für Effekte/Texturen/Grafiken/Icon-Sets zuerst references/asset-recipes.md öffnen (20 vorgefertigte Code-Fragmente: Lichtflecken, Sweep-Lights, Partikel, Glas, Neon, Grids, abstrakte Illustrationen, Wireframe-Kugeln, Diagramme, Stadt-Silhouetten, Glitch-Effekt, Scanlines, Icons-Set, Lichtstrahlen, Tiefenschärfe, Stoffmuster, Bokeh, Pseudo-3D). Wenn nichts Passendes dabei ist, selbst SVG-Pfade schreiben. Keine Emojis oder Unicode-Symbole als Grafiken verwenden. Jedes Bild muss mindestens drei Ebenen haben (Hintergrundverlauf/Grid → Hauptmotiv → Atmosphäre/Partikel/Bokeh), mindestens 2 selbst erstellte visuelle Elemente, 1 Tiefenhinweis (Schatten/Verlauf/Farbschichtung/Partikel). Nur eine Ebene mit Text und Farbflächen = nicht bestanden.
  8. Bestehende Assets haben Vorrang, nicht neu bauen. Wenn im Workspace bereits fertige Skelette/Spezifikationen/Komponenten/Designs vorhanden sind, müssen sie komplett übernommen werden, kein einziger Wert neu geschätzt. rigcheck.mjs --ref beweist, dass du die Originalwerte verwendest. Unfallbericht: Einmal wurde head.pos von [-6.8,-182.5] auf [0,-248] geändert (Abweichung 65.9px), torso.pv von [160,160] auf [160,291] (Abweichung 131px). Ergebnis: Der Kopf schwebte links vom Körper, aber „Bildkontrolle“ hat es nicht erkannt – weil das menschliche Auge es als „eine Figur“ interpretiert. Solche Fehler müssen numerisch erkannt werden.
  9. Material-Whitelist. Nur die im storyboard.md explizit gelisteten Materialien verwenden. Andere Dateien im Workspace (ältere Versionen, Bilder von anderen Charakteren, Konfigurationen anderer Projekte) dürfen nicht angerührt werden, selbst wenn sie nutzbar erscheinen. Neue Materialien: eine Zeile im Storyboard + Verwendungszweck angeben, dann suchen.
  10. Abnahme ohne Nachsicht, keine parallelen Renderings. audit meldet WARN ≠ „kann geliefert werden“: Harte Übergänge (jump) und einfarbige Frames (flat) müssen auf Null zurückgesetzt oder einzeln erklärt werden, sonst neu machen. verify/rigcheck mit FAIL – keine weitere Arbeit. Nur ein render.mjs-Prozess gleichzeitig – das Skript hat eine Sperre; parallel laufende Prozesse streiten sich nur um CPU. Für Parallelisierung innerhalb eines Chrome mehrere Tabs öffnen (siehe cinema-grade.md §9), nicht mehrere Prozesse starten.

Zahlen gehören zu Tools, Entscheidungen zu dir

Diese Modellklasse (Flash/mini/turbo) hat eine Tendenz: Lieber selbst schätzen, als Tools zu verwenden. Es hält Kopfrechnen für kostenlos, Tools für umständlich. Diese Kostenrechnung ist falsch. Rechnen wir es klar:

Kopfrechnenease.mjs aufrufen
Direkte Zeit0 Sekundenca. 0.3–0.5 Sekunden
Wahrscheinlichkeit, richtig zu liegen30–40% (ein falscher Bézier-Kontrollpunkt ändert die ganze Kurve)100%
Kosten eines Fehlers90 Frames rendern ≈ 8 Sek. + Bildprüfung, und man sieht den Fehler wahrscheinlich nicht, nur „es ist nicht ganz geschmeidig“0
Erwartete Kosten0 + 0.5 × (8 + 30) ≈ 19 Sekunden, plus stiller Qualitätsverlust0.5 Sekunden

Die 0.5 Sekunden, die du durch Kopfrechnen sparst, sind die teuerste Art zu sparen. Daher: harte Anforderung, kein Vorschlag.

Die folgenden Zahlen stammen ausschließlich von Tools. In deiner Antwort sind handgeschriebene Schätzwerte verboten:

Was brauchst du?Was läufst du?
Eigenschaften eines Bézier (Überschwingen, Plateau, Sample-Tabelle)node scripts/ease.mjs cubic 0.22 1 0.36 1
Federparameter (wie viel Überschwingen, wie lange, stoppt es mittendrin)node scripts/ease.mjs spring 120 14 1 1.2
Kurve als CSS linear() ausgebennode scripts/ease.mjs css-linear --preset silkIn
Staffelung einer Gruppe von Elementen, Gesamtzeit, ob sie überschreitetnode scripts/ease.mjs stagger 7 2.4 0.5
Textkontrast prüfennode scripts/ease.mjs contrast "#0b0e14" "#6d8bbd"
Lesbare Graustufen aus einer Hintergrundfarbe erzeugennode scripts/ease.mjs ramp "#0b0e14" 5

Drei Selbstchecks (vor der Abgabe fragen; kein „kann ich nicht beantworten“ erlaubt):

  1. Kann jeder Kurvenparameter in meiner Antwort auf einen vorherigen Befehl zurückgeführt werden?
  2. Habe ich irgendwo eine Zahl wie „wahrscheinlich um 0.3“ geschätzt? Ja → löschen, Befehl ausführen.
  3. Sage ich „diese Kurve ist geschmeidig“, weil ich die ASCII-Grafik und den Überschwing-Prozentsatz von ease.mjs gesehen habe, oder weil ich es rate?

Auch das Modell will sich selbst prüfen. Lass es den Verifikator nutzen: verify.mjs liest die echten berechneten Styles, nicht Schätzungen. Wenn es „nur bestätigen“ will, ist der korrekte Schritt verify auszuführen, nicht im Kopf zu simulieren.


Umgebung

Keine npm-Abhängigkeiten. Benötigt Chrome oder Edge (bereits auf dem System) + ffmpeg + ffprobe.

ffprobe wird nur für audit zur Überprüfung von Auflösung/Dauer verwendet. Fehlt, wird nicht stillschweigend ignoriert: Wenn --width/--height/--duration deklariert ist, FAIL; wenn nicht deklariert, WARN mit Nachricht „Auflösung unbekannt (nicht geprüft)“.

node scripts/render.mjs --check      # Zeige chrome / ffmpeg / node / WebSocket-Fähigkeit

Wenn chrome als NOT FOUND ausgegeben wird, mit --chrome <pfad> angeben oder zuerst einen Browser installieren.

Was tun, wenn kein Bildverständnis vorhanden ist?

Manche Modelle (z. B. reine Text-Inferenz-Versionen) können read_image nicht verwenden. Diese Pipeline basiert vollständig auf Zahlen, nicht auf Bildern, also kann sie trotzdem durchlaufen: ease (Parameter) → verify (numerische Trajektorie + Idempotenz) → audit (Pixelstatistik, Ergebnis ist Zahl) → rigcheck (geometrische Zusicherungen).

  • Möglich: Struktur, Bewegung, Geometrie, Lesbarkeit
  • Nicht möglich: Kompositionsqualität, Farbharmonie, Stil-Konsistenz, visuelle Clipping-Fehler

Letztere müssen von einem Menschen (oder einem visuellen Modell) beurteilt werden. Aber das kann aufgeschoben werden: Zuerst mit Zahlen alle erkennbaren Fehler abfangen, dann dem Menschen 6–8 Frames zeigen (--still Batch + --guides Sicherheitszonen).


Dokumentenverzeichnis (Nach Bedarf lesen, nicht alles auf einmal lesen)

DateiWann lesen?
references/wish-mode.mdWenn der Benutzer nur einen Satz sagt, zuerst lesen: Vier Slots, Kapitelableitung, Standardwerte, kein Interview im Wunschmodus
references/spec-and-prompt.mdBeim Schreiben der Spezifikationstabelle (STEP 1); wenn reproduzierbare Prompt-Vorlagen benötigt werden; gegen Modelle, die keine Tools verwenden wollen
references/code-patterns.mdBeim Schreiben von Code (STEP 2): seek(t)-Paradigma, Easing-Bibliothek, keys()-Keyframe-Tabelle, spring(f,z), SVG/Canvas, 20 moderne CSS-Effekte
references/asset-recipes.mdWenn das Bild etwas braucht, sofort öffnen: Lichtflecken, Sweep, Partikel, Glas, Neon, Grids, Illustration, Partikel, Wireframe-Kugel, Diagramm, Icon-Set, Bokeh, Pseudo-3D
references/rig-characters.mdWenn eine Figur im Bild sich bewegt: Teile + Parent-Child-Transformationskette + Pose-Tabelle + 12 Prinzipien auf Felder umsetzen
references/cinema-grade.mdVor der Finalisierung: Bewegungsunschärfe, Encoding-Parameter (gegen Banding), Vignette, HUD-System, Wisch-Effekte, Bildratenwahl, Lange-Filme-Organisation, Parallelbeschleunigung
references/review-checklist.mdSTEP 5: Menschliche Stichprobe + alle Prüfpunkte vor der Abgabe
references/failure-modes.mdBei Fehlern von audit/verify nachschlagen
references/delta-vs-opus.mdWenn du wissen willst, „wie weit dieses System kommt“, und entscheiden musst, ob du das Modell wechseln sollst

Zuerst aufteilen: Wunsch- oder Spezifikationsmodus

EingabeformWeg
Liefert die meisten Informationen (Größe/Dauer/Inhalt/Stil) oder antwortet auf RückfragenSpezifikationsmodus: STEP 0 nachfragen → STEP 1 Spezifikationstabelle → …
Ein Satz + autorisierender Ton („Mach was Beeindruckendes“, „Zeig deine Fähigkeiten“, „Wie ein bestimmter Film“, „Gib Vollgas“)Wunschmodus: STEP 0 überspringen, nicht nachfragen. Zuerst Workspace scannen, Motiv finden, vier Slots füllen, dann ab STEP 1 arbeiten. Siehe wish-mode.md

Die Entscheidung ist einfach: Hat er nicht alles gesagt, ist es „warte auf meine Frage“ oder „entscheide du“? Ein Ton wie „mach was du kannst/Vollgas/zeig es mir“ ist Letzteres. Im Wunschmodus muss ebenfalls ein storyboard.md erstellt werden – nur dass die Tabelle von dir gefüllt wird, nicht durch Fragen.

Arbeitsablauf

STEP 0 · Kläre drei Dinge (nur im Spezifikationsmodus; Wunschmodus überspringen)

  • Anwendungszweck: Vorspann / Social-Media-Kurzvideo / Web-Hero-Animation / Erklär-Schnipsel / Datenwachstumsanimation / GIF
  • Größe und Dauer: Siehe Standardwerte unten, es sei denn, der Benutzer gibt explizite Angaben.
  • Stimmung: Ruhig (Business/Finanzen), Schnell (Tech/Launch), Sanft (Leben/Marke), Hart (Spiele/Sport)
AnwendungszweckGrößeDauerBildrateFormat
Vorspann / Launch1920x10803–6s30mp4
Social-Media-Hochformat1080x19205–15s30mp4
Web-Hero / Banner1920x800 oder 1440x6002–4s, endlos wiederholbar30webp / apng (mit Transparenz); webm nur nach Alpha-Überprüfung
Datenanimation / Diagramm1920x10803–8s30mp4
Endlos-GIF800x800 / 1080x10801–3s, nahtlos wiederholbar15–20gif / webp
Erklär-Schnipsel1920x10802–5s pro Einstellung, dann ganzer Film zusammensetzen30mp4

Länger als 10 Sekunden oder mehr als 3 Einstellungen: In mehrere Szenendateien aufteilen, jede einzeln rendern und prüfen, dann mit ffmpeg zusammensetzen. Kein einziges seek() über 30 Sekunden – das kann niemand selbst überprüfen.

STEP 1 · Spezifikation schreiben (einziger Schritt für kreative Freiheit)

Erstelle storyboard.md. Beides ist notwendig:

① Aufnahmetabelle

#ZeitWas passiert im BildHauptbewegungEndzustand
10.00–1.10sTitel schwebt Zeichen für Zeichen einy: +96→0, je Zeichen 75ms VersatzTitel ist sichtbar
21.10–2.40sFortschrittsbalken füllt sich + drei Punkte erscheinenscaleX: 0→1 (ease in out)Linie am Rand, Punkte fertig

② Element-Zeitachsen-Tabelle (eine Zeile pro Element, das ist die alleinige Grundlage für den Code)

ElemententeractiveexitAttributeKurve
#title span0.15 + i*0.075bis Ende—translateY 96→0, opacity 0→1easeOutCubic
#bar b0.300.30–2.40—scaleX 0→1easeInOutCubic
.dots i1.50 + i*0.15bis Ende—scale 0→1easeOutBack

Wenn du diese Tabelle nicht schreiben kannst, hast du es noch nicht durchdacht. Überspringe sie nicht und schreibe Code – der wird nur „erster und letzter Frame“ enthalten.

Die Spalte „Kurve“ bedeutet nicht, dass du nur einen Namen hinschreibst. Wenn der Name feststeht, sofort das Tool ausführen, um „wie diese Kurve bei deiner Dauer wirkt“ festzustellen, und die Zeile mit einem Zahlenwert ergänzen:

node scripts/ease.mjs cubic 0.33 1 0.68 1     # easeOutCubic → Plateau-/Overshoot-Prüfung
node scripts/ease.mjs stagger 6 2.4 0.7       # 6 Titelbuchstaben in 2.4s, jeder 0.7s → Staffelung und Überschreitung

Die Tabelle sieht dann so aus:

ElemententeractiveexitAttributeKurve (Tool-bestätigt)
#title span0.15 + i*0.075bis Ende—translateY 96→0, opacity 0→1cubic-bezier(0.33,1,0.68,1), overshoot 0%, nach 0.75 Plateau-Abschnitt → Dauer auf <0.7s begrenzen
.dots i1.50 + i*0.15bis Ende—scale 0→1spring(120,14) overshoot 7.1%, stabil nach 0.67s → Abschnittslänge 0.75s

Kriterien für eine gute Kurve (das Tool sagt es dir direkt): Overshoot ≤ 15%, kein mittleres Plateau, Stabilisierungszeit der Feder ≤ Abschnittslänge. Wenn eine Bedingung nicht erfüllt ist, Parameter ändern und erneut ausführen, nicht „erstmal so schreiben und rendern“. Nichts mit dem Auge prüfen.

Vorlage und weitere Paradigmen: references/spec-and-prompt.md

STEP 2 · Implementierung

Beginne mit einem Grundgerüst, schreibe nicht die ganze Szene auf einmal. Grundgerüst = Hintergrund + ein animiertes Element + seek-Vertrag erfüllt.

window.scene = {
  duration: 3.0, fps: 30, width: 1920, height: 1080, ready: true,
  seek(t) {
    // Jedes Element: Die Zeile aus der Zeitachsen-Tabelle in 3 Codezeilen übersetzen
    // k = kurve(seg(t, enter, enter + dauer)) → k zur Interpolation des Attributs verwenden
  },
};

CSS und JS müssen inline sein. Keine externen CDNs (Rendering wird dann wie ein Netzwerkausfall fehlschlagen). Systemschriftarten verwenden ("Segoe UI", "Microsoft YaHei", Arial).

Mögliche Paradigmen (DOM/CSS/SVG/Canvas/GSAP/Web Animations, Easing-Bibliothek, Mehrfach-Orchestrierung, Buchstabe-für-Buchstabe, Path-Stroke, Scroll-Number, Mask-Transition, CSS linear(), filter/blend-mode/mask): references/code-patterns.md

Wenn etwas gezeichnet werden muss (Lichteffekte, Texturen, Grafiken, Icons, Diagramme, Illustrationen, Pseudo-3D): Zuerst references/asset-recipes.md öffnen. Dort gibt es 20 abhängigkeitsfreie Code-Fragmente, die alle in eine einzelne HTML-Datei eingefügt und von seek(t) gesteuert werden können. Nicht von Grund auf neu erfinden und nicht auf Materialien warten.

STEP 3 · Numerische Prüfung (zuerst Zahlen prüfen, nicht gleich rendern)

Dies ist der erste Schritt in der „mehr Prüfungen“-Kette: dauert Sekunden, kein Encoding, und kann Elemente direkt benennen.

# Sieh die tatsächliche Trajektorie jedes Elements: wer sich bewegt, wohin, wo es hängt
node scripts/verify.mjs --html scene.html --select "#bar b,#title span" --props transform,opacity --steps 31

# Prüfen, dass das Bild nur von t bestimmt wird (zweimal derselbe t muss identische Pixel ergeben)
node scripts/verify.mjs --html scene.html --select ".item" --idempotent

Es gibt dir direkt die Antworten:

  • ⚠ #b[0] · sx — Pause auf halbem Weg 0–2s, dann weiter verändert → Interpolation wurde unterbrochen oder fehlt
  • ℹ #card[0] · (alle) — Dieses Element hat sich während des gesamten Abschnitts nicht verändert → Selektor trifft nicht / Style nicht im DOM
  • ✖ seek nicht idempotent: 13 Stellen mit unterschiedlichen Ergebnissen bei gleichem t → seek verwendet Akkumulationsstatus

Wenn der numerische Layer bestanden ist, weiter. Nicht das ganze Video rendern, wenn die Zahlen falsch sind – das bringt nur eine vage „Bild scheint sich nicht zu bewegen“-Diagnose und du musst von Pixeln zurückverfolgen. Lass zuerst die Zahlen sprechen.

STEP 4 · Rendern + Pixel-Abnahme

Zuerst nur Keyframes ausgeben, schnell, um die Komposition zu prüfen:

node scripts/render.mjs --html scene.html --still 0.2,1.0,2.2 --out out/stills

Diese Bilder ansehen (mit read_image selbst, nicht überspringen). Wenn die Komposition passt, das ganze Video:

node scripts/render.mjs --html scene.html --out out/v.mp4 --fps 30 --sheet
node scripts/audit.mjs --video out/v.mp4 --fps 30 --duration 3 --width 1920 --height 1080

audit gibt dir: Änderungspixel-Kurve, Rhythmusbalken, und eine bewertende Schlussfolgerung. Nach der Schlussfolgerung ändern, jedes Mal nur eine benannte Stelle, dann sofort audit erneut ausführen. Maximal 5 Runden; wenn die 5. Runde immer noch FAIL ist, zurück zu STEP 1 und die Spezifikation ändern (das heißt, die Spezifikation selbst war falsch).

Häufige Fehler finden: references/failure-modes.md

STEP 5 · Menschliche Stichprobe

Die Maschine prüft nur „Struktur korrekt“. Diese Punkte musst du selbst ansehen:

  • Läuft Text über den Bildrand / wird abgeschnitten / kollidiert mit dem Hintergrund?
  • Ist der visuelle Schwerpunkt an der erwarteten Position (Drittelung / Zentrum / Schwerpunkt der Elementgruppe)?
  • Ist der Kontrast ausreichend (grauer Text mit 40% Deckkraft auf dunklem Hintergrund ist unsichtbar)?
  • Sind Ein- und Ausgänge sauber (beginnt ein Element außerhalb des Bildes? verschwindet es plötzlich innerhalb des Bildes)?

Checkliste: references/review-checklist.md

STEP 6 · Abgabe

# Für jedes benötigte Format einen weiteren Befehl
node scripts/render.mjs --html scene.html --out out/v.webm --format webm
node scripts/render.mjs --html scene.html --out out/v.gif --format gif --fps 15

Abgabe: Pfad des Videos, Kontaktabzug, audit-Veridikt (die paar Zeilen), storyboard.md. Wenn audit WARN hat, du es aber als designintern betrachtest, benenne die Zeile und gib den Grund an.

Die endgültige Version muss mit Bewegungsunschärfe neu gerendert werden.

node scripts/render.mjs --html scene.html --out out/final.mp4 --fps 30 --motion-blur 180

Das ist die Grenze zwischen „sieht geschmeidig aus“ und „sieht aus wie ein Screenshot“. In der Iterationsphase kann Bewegungsunschärfe vorübergehend ausgeschaltet werden, um Zeit zu sparen, aber die Abgabeverion darf keinen Verschluss vermissen lassen – das zu sparen, bedeutet Qualitätsverlust. Nach dem Einschalten audit erneut ausführen, um sicherzustellen, dass Dauer und Bildrate nicht geändert wurden. Bei schnellen Bewegungen (Charakter-Aktionen, Wisch-Effekte, Partikel) gleichzeitig --fps 60 verwenden.


Befehls-Schnellreferenz

# System-Check
node scripts/render.mjs --check

# Berechnungen (Kurven / Feder / Staffelung / Kontrast) — diese niemals im Kopf rechnen
node scripts/ease.mjs cubic 0.22 1 0.36 1
node scripts/ease.mjs spring 120 14 1 1.2
node scripts/ease.mjs css-linear --preset silkIn
node scripts/ease.mjs stagger 7 2.4 0.5
node scripts/ease.mjs contrast "#0b0e14" "#6d8bbd"
node scripts/ease.mjs ramp "#0b0e14" 5
node scripts/ease.mjs presets

# Skelett-Geometrie-Check (bei Charakteren immer; bei vorhandenem Rig muss --ref für Alignment)
node scripts/rigcheck.mjs --rig rig/ander.rig.json
node scripts/rigcheck.mjs --rig lib/rig.json --ref rig/ander.rig.json
node scripts/rigcheck.mjs --rig rig.json --pose '{"head":{"rot":0.2}}' --assert

# SKILL.md-Frontmatter-Check (nach jeder Änderung am Skill ausführen, um zu verhindern, dass „das ganze Skill nicht geladen wird“)
node scripts/lint-skill.mjs

# Numerische Prüfung (Sekundenbruchteile, benennt Elemente)
node scripts/verify.mjs --html scene.html --select "#bar b" --props transform,opacity --steps 31
node scripts/verify.mjs --html scene.html --select ".item" --idempotent
node scripts/verify.mjs --html scene.html --all --json

# Keyframes (für die Bildprüfung, am schnellsten)
node scripts/render.mjs --html scene.html --still 0,0.5,1.5,2.9 --out out/stills

# Keyframes + Kompositionshilfslinien (100px Raster / 80px Sicherheitszone / Drittelungslinien / zentrales Kreuz)
node scripts/render.mjs --html scene.html --still 1.6 --guides --out out/guides

# Gesamtes Video + Kontaktabzug
node scripts/render.mjs --html scene.html --out out/v.mp4 --fps 30 --sheet

# Finale Abgabe mit Bewegungsunschärfe (180° Verschluss = Kinostandard; Rendering ×4, nur zur Finalisierung)
node scripts/render.mjs --html scene.html --out out/final.mp4 --fps 30 --motion-blur 180

# Nur bei schnellen Bewegungen (Charakter-Aktionen, Wisch-Effekte, Partikel) 60fps
node scripts/render.mjs --html scene.html --out out/final.mp4 --fps 60 --motion-blur 180

# 2x Supersampling (schärfer, 3–4× langsamer)
node scripts/render.mjs --html scene.html --out out/v.mp4 --scale 2

# Transparenter Hintergrund: webp / apng / png zuverlässig
node scripts/render.mjs --html scene.html --out out/v.webp --format webp --alpha
node scripts/render.mjs --html scene.html --out out/v.apng --format apng --alpha

# webm-Alpha hängt vom ffmpeg-Build ab. Lokal getestet: VP8/VP9 stufen auf kein Alpha zurück.
# Skript liest nach dem Encoding den ersten Frame zurück und prüft auf Alpha-Pixel – wenn keine vorhanden, Fehler mit Hinweis auf Alternative.
node scripts/render.mjs --html scene.html --out out/v.webm --format webm --alpha

# Endlos-GIF
node scripts/render.mjs --html scene.html --out out/v.gif --format gif --fps 15

# Pixel-Abnahme
node scripts/audit.mjs --video out/v.mp4 --fps 30 --duration 3 --width 1920 --height 1080
node scripts/audit.mjs --video out/v.gif --loop           # Nahtlosigkeitsprüfung
node scripts/audit.mjs --video out/v.mp4 --json out/audit.json

render.mjs Parameter: --html --out --fps --duration --width --height --scale --format(mp4|webm|gif|webp|apng|png) --still --sheet --alpha --file --keep-frames --chrome --check --quiet verify.mjs Parameter: --html --select --props --steps --all --idempotent --json --rig --ref --pose --assert --video --duration --width --height --quiet audit.mjs Parameter: --video --fps --duration --width --height --changelog --json --loop --quiet scripts/ease.mjs Parameter: Siehe node scripts/ease.mjs --help.


Häufige Fehler & Reparaturen

SymptomUrsacheReparatur
"WARN — flat frame(s) detected"Ein oder mehrere Frames haben weniger als 5% sich ändernde Pixel1. --still auf die flat-Frames prüfen 2. In der Zeitachsen-Tabelle: Kann ein Element zu früh wieder verschwinden? Ist ein exit-Intervall zu kurz? 3. ease-Tool prüfen: Overshoot zu niedrig zwischen den Frames? 4. Am Ende keine Bewegung → Verlängerung des active-Abschnitts prüfen
"FAIL — jump detected"Ein Pixel-Kanal springt zwischen zwei Frames um mehr als 25/2551. Bezier-Overshoot zu groß? ease.mjs prüfen 2. Fast Movement ohne 60fps + motion-blur? → --fps 60 und motion-blur aktivieren 3. — Ein Element wird zu spät eingeblendet / zu früh ausgeblendet → enter/active/exit prüfen
"WARN — 30% clamped value range"Die Animationseigenschaft wird nur teilweise ausgenutzt (z.B. opacity läuft nur von 0,8–1,0)Prüfen, ob der Start-/Endwert in der Tabelle korrekt ist; ggf. Bereich ausweiten
"WARN — static tail"Die letzten 20% der Dauer haben keine PixeländerungEnde der Animation auffüllen: Nachklang-Effekt, End-Element still stehen lassen, oder kürzen
"FAIL — seek not idempotent"seek(t) verwendet Akkumulationsstatus (z.B. +=), Date.now() oder performance.now()Alle Zustände als Funktion von t umschreiben; sicherstellen, dass t von 0 bis duration wiederholt aufgerufen werden kann
verify sagt „Element nicht gefunden“ und überspringt die PrüfungCSS-Selektor passt nicht / Element im DOM nicht vorhanden / Style nicht inline--select korrigieren oder prüfen, ob das Element sichtbar ist
audit meldet „Auflösung unbekannt“Kein --width/--height angegeben--width 1920 --height 1080 anfügen
rigcheck meldet „Schulter aus der Pose“Posenparameter nicht mit --ref abgeglichen--ref mit der Original-Rig-Datei angeben; dann die abweichenden Werte korrigieren

Weitere Modi: references/failure-modes.md


Kurzes Beispiel: Ein Titel schwebt ein

storyboard.md

Aufnahmetabelle

#ZeitBildHauptbewegungEndzustand
10.00–2.00sTitel „Hello World“ schwebt Buchstabe für Buchstabe von unten einy: 120→0, je Buchstabe 80ms, opacity 0→1Titel vollständig sichtbar

Element-Zeitachsen-Tabelle

ElemententeractiveexitAttributKurve (Tool bestätigt)
.char i0.10 + i*0.08bis 2.00—translateY 120→0, opacity 0→1easeOutCubic → cubic-bezier(0.33,1,0.68,1), overshoot 0%, 0.75s nach Einblendung stabil

Implementierung

<!DOCTYPE html>
<html>
<head>
<style>
  body { margin:0; background: #0b0e14; display:flex; justify-content:center; align-items:center; height:100vh; font-family:"Segoe UI",sans-serif; }
  .char { display:inline-block; will-change:transform,opacity; font-size:4rem; color:#e0e6f0; }
</style>
</head>
<body>
<div id="scene">
  <div id="title">
    <span class="char">H</span><span class="char">e</span><span class="char">l</span><span class="char">l</span><span class="char">o</span><span class="char"> </span><span class="char">W</span><span class="char">o</span><span class="char">r</span><span class="char">l</span><span class="char">d</span>
  </div>
</div>
<script>
window.scene = {
  duration: 2.0, fps: 30, width: 1920, height: 1080, ready: true,
  seek(t) {
    const chars = document.querySelectorAll('.char');
    chars.forEach((el, i) => {
      const enter = 0.10 + i * 0.08;
      const dur = 0.75;
      const progress = (t - enter) / dur;
      if (progress <= 0) {
        el.style.transform = 'translateY(120px)';
        el.style.opacity = 0;
      } else if (progress >= 1) {
        el.style.transform = 'translateY(0)';
        el.style.opacity = 1;
      } else {
        const k = 1 - Math.pow(1 - progress, 3); // easeOutCubic: 1 - (1 - t)^3
        el.style.transform = `translateY(${120 * (1 - k)}px)`;
        el.style.opacity = k;
      }
    });
  }
};
</script>
</body>
</html>

Ausführen & Prüfen

# 1. Numerische Prüfung
node scripts/verify.mjs --html scene.html --select ".char" --props transform,opacity --steps 21

# 2. Keyframes zur Ansicht
node scripts/render.mjs --html scene.html --still 0,0.3,0.8,1.5,2.0 --out out/stills

# 3. Komplett rendern + audit
node scripts/render.mjs --html scene.html --out out/v.mp4 --fps 30 --sheet
node scripts/audit.mjs --video out/v.mp4 --fps 30 --duration 2 --width 1920 --height 1080

# 4. Finale Version mit Bewegungsunschärfe
node scripts/render.mjs --html scene.html --out out/final.mp4 --fps 60 --motion-blur 180

Verwandte Skills