Files
RUWIO/docs/macro-clips-testing.md
T
thandClaude Opus 4.7 6471c446df docs: testing walkthrough for the macro-clips feature set
Covers the end-to-end flows per slice: markers (m shortcut + scrub-
ruler interactions), script tracks/frames (open dialog, action types,
forward-only firing rules), button clip creation and drag-to-track,
ButtonInstance dialog (label, onClick, disabled, transitions), canvas
runtime (pointer state machine, drag-out cancel behavior, scripted
state flips), transitions (matched layer blend vs crossfade, easing),
the DSL language reference with examples, a quick sanity pass for the
HTML export runtime, and which in-app test suites to look for.

Also documents the two known limitations (no in-app button state
authoring, scripts not baked into the server PNG/MP4 render) and a
small devtools cheat sheet for poking the pinia store directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 21:52:12 +02:00

8.7 KiB

Macro Clips & Scripts — Testing Guide

Eine Walkthrough für die Features aus docs/macro-clips-and-scripts.md. Start: App mit npm run dev, leeres Projekt öffnen („New Project" im Welcome-Dialog).


1. Marker

Ziel: Sprungziele auf der Haupt-Timeline setzen und benennen.

  1. Playhead an eine beliebige Stelle ziehen (z. B. t = 2 s).
  2. m drücken → ein Marker wird an der Playhead-Position angelegt und ein Rename-Prompt öffnet sich. Namen eingeben (z. B. intro), Enter.
  3. Marker erscheint als kleine Fahne oben auf der Scrub-Ruler.
  4. Interaktionen am Marker:
    • Einfacher Klick → Playhead springt dort hin.
    • Drag → Marker zeitlich verschieben.
    • Doppelklick → Rename.
    • Marker anwählen, Backspace/Delete → löscht ihn. Esc → entauswählt.

Erwartung:

  • Mehrere Marker bleiben zeitlich sortiert.
  • Zweiter Marker mit gleichem Namen bekommt automatisch Suffix (intro 2).
  • Namen müssen Scene-weit unique sein (Rename zeigt Fehler-Dialog bei Kollision und öffnet den Prompt erneut).

2. Script-Tracks & Action-Frames

Ziel: Zeit-gebundene Aktionen definieren, die bei Playback feuern.

  1. Im Timeline-Header die Code-Taste (</>-Icon) klicken → ein neuer Script-Track wird angelegt (kleinere Zeile als Clip-Tracks).
  2. Auf der leeren Script-Lane an beliebiger Zeitposition klicken → ein neuer Action-Frame wird erstellt und der ScriptFrameDialog öffnet sich.
  3. Im Dialog Add action drücken → ein Dropdown zeigt alle Action-Typen.
    • Beispiel: Pause auswählen → nur Typ, keine Params nötig.
    • Weitere Action hinzufügen: Jump to marker → Marker-Name aus dem Dropdown wählen (dafür muss aus Schritt 1 ein Marker existieren).
  4. Dialog schließen mit Done.
  5. Mehrere Actions pro Frame sind erlaubt — die Zahl rechts neben dem Frame-Dot zeigt deren Anzahl.

Testen:

  • Playhead VOR den Action-Frame ziehen, dann Space (Play).
  • Playback läuft, und genau wenn der Playhead über den Frame hinausgeht, feuern die Actions in Listen-Reihenfolge.
  • Beispiel pause + jumpToMarker intro → Playback pausiert und Playhead springt zum intro-Marker.

Erwartung:

  • Beim Scrubben (Ziehen des Playheads oder Marker-Klick) feuern keine Actions.
  • Beim Loop-Wrap (von playbackOut zurück nach playbackIn) feuern ebenfalls keine Actions.
  • Rückwärtsbewegen der Zeit feuert nichts.

3. Button-Clips erzeugen und platzieren

Ziel: Einen klickbaren Button definieren, auf die Stage bringen und onClick-Actions hinterlegen.

  1. In der Asset-Sidebar den Abschnitt Buttons → + klicken. Namen eingeben (z. B. PlayButton), Enter.
  2. Der Button erscheint in der Liste mit einem Cursor-Icon. Die 4 States sind automatisch als bunte Rects vorausgefüllt (blau / hellblau / dunkelblau / grau).
  3. Button-Clip aus der Sidebar auf eine Clip-Track ziehen (Drag-and-Drop).
    • Wenn keine Clip-Track existiert, in den Timeline-Bereich unter den Tracks droppen → neue Clip-Track entsteht automatisch.
  4. Auf der Clip-Track erscheint ein 4-Zellen-Block (N H P D) an der Drop-Position.
  5. Auf dem Canvas erscheint der Button (standardmäßig in der Stage-Mitte) — wenn der Playhead ≥ Instanz-Startzeit.

Button editieren:

  1. Auf den 4-Zellen-Block klicken → ButtonInstanceDialog öffnet sich.
  2. Label vergeben (z. B. play) — wichtig, weil:
    • Im DSL über btn:play referenzierbar.
    • Im Dropdown von Set button state-Actions sichtbar.
  3. On click → Actions definieren (z. B. Play und Jump to marker intro).
  4. Start disabled aktivieren → Button startet grau/schraffiert, reagiert nicht auf Klicks.
  5. Done.

4. Button-Runtime auf der Stage testen

Voraussetzung: Ein Button ist platziert und der Playhead ist auf oder nach dessen Startzeit.

  1. Maus über den Button bewegen → Farbe wechselt zu hellblau (hover).
  2. Maus-Down → Farbe wird dunkelblau (pressed).
  3. Maus-Up (immer noch im Button) → onClick-Actions feuern; State geht zurück zu hover.
  4. Maus-Down und rausziehen vor dem Maus-Up → kein onClick, State kehrt zu normal zurück (Standard-Browser-Button-Verhalten).
  5. Disabled-Button hat keine Hover-/Press-Reaktion, ignoriert Klicks.

Skript-getriggert:

  • In einem ScriptFrame eine Set button state-Action mit Target = Button-Label und state = pressed anlegen.
  • Beim Playback überqueren → der Button schaltet visuell in pressed, ohne dass der User hovert.
  • Set button disabled / Enable toggelt den Disabled-Flag zur Laufzeit.

5. Transitions zwischen States

Ziel: Glatter visueller Übergang zwischen States statt hartem Wechsel.

  1. ButtonInstance-Dialog öffnen (4-Zellen-Block klicken).
  2. Unter Transitions → + Add transition.
  3. Zeile: normal → hover, Duration 0.15, Easing easeOut.
  4. Weitere Zeile: hover → normal, Duration 0.2, Easing easeOut.
  5. Done.
  6. Auf dem Canvas Maus über den Button → die Farbe fadet zwischen Blau und Hellblau über 150 ms, statt instant zu wechseln.

Hinweise:

  • Transitions sind Clip-scoped, d. h. sie gelten für alle Instanzen des Buttons.
  • Layer werden zwischen den beiden States per name gematcht (beim Default-Seed heißen alle Face-Layer schlicht Face → werden immer interpoliert). Unmatched Layer faden nur rein/raus (Crossfade).
  • Ohne Transition: State-Wechsel ist sofort (Verhalten wie vor Slice 7).

6. Script-DSL testen

Ziel: Komplexere Logik in einer kompakten Textform statt manuellem Zusammenklicken mehrerer Actions.

  1. ScriptFrameDialog öffnen (oder ButtonInstanceDialog).
  2. Add action → Typ Run script wählen.
  3. Im Textarea:
    // setzt Pause und springt an den intro-Marker
    pause
    jump @intro
    state btn:play pressed
    disable btn:play
    
  4. Done.

Testen:

  • Frame überqueren → alle parsed Aktionen feuern in Reihenfolge.
  • Falsche Syntax → Warnung erscheint in der Devtools-Konsole ([animatr] Script line N: ...). Die fehlerhafte Zeile wird übersprungen; valide Zeilen feuern trotzdem.

DSL-Referenz (aktueller Sprachumfang):

// Kommentar (bis Zeilenende)

play                    // Playback starten
pause                   // Playback pausieren
rewind                  // Playhead → playbackIn (in-point)

jump 2.5                // Zeit in Sekunden
jump #135               // Frame-Nummer (durch fps geteilt)
jump @markerName        // benannter Marker

state btn:label <state>    // <state> ∈ normal|hover|pressed|disabled
enable  btn:label
disable btn:label

7. Export-Runtime prüfen

Ziel: Sicherstellen dass Buttons, Scripts, Marker im exportierten Projekt genauso funktionieren wie im Editor.

  1. Menü → Export (oder beliebiger Export-Trigger je nach UI).
  2. AnimatrPlayer-HTML-Export wählen → Datei öffnen im Browser.
  3. Erwartet:
    • Buttons rendern an ihren Positionen, mit Pointer-Reaktion.
    • onClick feuert die hinterlegten Aktionen (z. B. jump @intro springt im exportierten Player-Playhead zum Marker).
    • Transitions animieren sauber.
    • Script-Frames feuern bei natürlichem Playback.
  4. Devtools-Konsole im Export-Tab → window.AnimatrPlayer.__v sollte '6' ergeben. Cache-Probleme? Hard-Reload mit Shift+Cmd+R / Ctrl+F5.

8. Runtime-Tests (in-app)

Ctrl+Shift+Alt+T öffnet den Test-Runner. Relevante Suiten:

  • scene store — markers / script tracks & frames / button clips & instances
  • actions — evalAction with mock runtime
  • actions — script type expands via evalAction
  • scriptDsl — parser
  • button runtime — state machine + action wiring
  • scene store — tick fires script frames forward-only

Alle sollten grün laufen.


Bekannte Einschränkungen

  • Kein Button-State-Editor in der UI: Die 4 States sind beim Seed mit farbigen Rects vorausgefüllt. Um die Optik anzupassen müsste man aktuell scene.buttonClips[i].states[…] direkt im gespeicherten Projekt-JSON editieren. Ein eigener Edit-Modus ist geplant, aber nicht implementiert.
  • Server-Render (PNG-Sequence / MP4) bakt Script-Actions und Button-Interaktionen bewusst nicht ein — das wäre keine deterministische Animation mehr. Scripts wirken nur in der interaktiven Browser-Laufzeit (Editor + AnimatrPlayer-HTML-Export).

Devtools-Cheat-Sheet

Für Tests ohne UI:

// Pinia store im Devtools:
const s = __pinia.state.value.scene
const store = useSceneStore() // im Vue-Devtools verfügbar

// Button-Instanz direkt einen bestimmten State geben:
const rt = useButtonRuntime()
rt.setState(instanceId, 'pressed')
rt.reset()

// Alle Marker sehen:
console.table(store.scene.markers)

// Alle Button-Instanzen:
console.table(store.scene.buttonInstances)