Commit Graph
66 Commits
Author SHA1 Message Date
thandClaude Opus 4.7 fb58cd18f7 macro-clips slice 8: script DSL parser + runtime label resolution
- src/lib/scriptDsl.ts: small line-based parser producing Action[] plus
  a list of ParseError{line,message}. Handles: play/pause/rewind,
  jump <sec> | #<frame> | @<marker>, state btn:<label> <state>,
  enable/disable btn:<label>, // comments, skips blanks
- evalAction for type:'script' parses the source and recursively
  dispatches sub-actions; errors surface via rt.warn
- ActionRuntime.setButtonState/setButtonDisabled are documented as
  taking an instance id OR a label; the store's actionRuntime builds
  a label→id map and resolves refs before applying
- exportPlayer template gets a matching parseScriptSource plus
  resolveButtonRef; evalAction-in-engine mirrors the TS version
- RUNTIME_VERSION bumped to '4'
- tests: parser covers commands, comments, jump variants, state/enable
  errors, unknown commands; two integration tests verify that script
  actions dispatch via evalAction and that parse errors don't block
  valid actions

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 21:20:15 +02:00
thandClaude Opus 4.7 8817a73c3d macro-clips slice 5: action evaluator + forward-only script frame firing
- new src/lib/actions.ts:
  - ActionRuntime interface (fps, range, markers, setPlayhead/play/pause,
    setButtonState/setButtonDisabled, warn)
  - evalAction dispatches each action kind, with clamping to [0, duration]
    for time-based jumps and a warning path for unknown markers and for
    script actions (DSL lands in slice 8)
  - scriptFramesInRange helper returns frames in the open-closed interval
    (prev, next], sorted
- store wires it up:
  - tick captures prevPlayhead, advances, then fires script frames that
    fall in (prev, landed]. Scrubs via setPlayhead never touch this path
    so the forward-only guarantee falls out of the architecture.
  - actionRuntime() builds an ActionRuntime bound to this store
  - setButtonState is a no-op in the editor for now (waits for the
    button-runtime slice); setButtonDisabled goes to the store action,
    rewindToLoop/play/pause/jumps mutate the store directly
- tests: 10 evaluator tests against a mock ActionRuntime covering all
  action kinds + marker map + scriptFramesInRange; 3 integration tests
  for tick firing (ordering, no-fire-on-scrub, firing-at-playbackOut)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 21:00:59 +02:00
thandClaude Opus 4.7 a75e9151ed macro-clips slice 1: types + store for buttons, scripts, markers
- ButtonClip/ButtonInstance, ScriptTrack/ScriptFrame, Marker, Action union
- new optional scene collections (buttonClips, buttonInstances, scriptTracks,
  scriptFrames, markers); normalizeScene initializes them on load
- store actions for all new entities, marker name + button label uniqueness,
  time clamping, cascading deletes (script frames with their track, button
  instances with their clip), script tracks join trackOrder + setTrackLocked
- design doc docs/macro-clips-and-scripts.md
- tests cover add/remove/rename/retime paths, uniqueness, sort order,
  label collisions, and normalization

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 20:34:44 +02:00
thandClaude Opus 4.7 d4c4830fe2 0.6.0: background video, in/out range, top-level masks, track icons
- background video layer (document-level), syncs to playhead in editor and fullscreen
- playback in/out brackets on the scrub ruler; i/o set them, r rewinds to in-point
- togglePlay, tick, fullscreen loop, WebM + server FFmpeg export all honor [in, out]
- top-level mask layers cascade over everything below until a group boundary
- fullscreen preview slaves localTime to the bg video so it stops stuttering
- welcome "new project" now actually loads a blank scene (was a no-op)
- default canvas background hardened to white via normalizeScene
- new keyframe button (+) in the name-spacer, backspace/delete removes selected kfs
- drag-end auto-selects the created/shifted keyframe so the path is visible
- animation path updates live during drag and spans every selected keyframe
- track rows show an icon per asset kind (rect/circle/image/text/polygon/freeform)
- default mask mode is negative, buttons read − then +
- sticky track-name columns raised above playhead/brackets; orange bracket styling
- tests for playback range, blank scene, mask defaults, cascading top-level masks

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 20:19:34 +02:00
thandClaude Opus 4.7 69de48ea8d 0.5.6: show/hide locked tracks + group lock + crop/mask-preview split
- Timeline: new show/hide toggle next to snap; locked tracks (including
  layer, clip, and the new group lock) are filtered from the timeline
  when the toggle is off. Preference lives in localStorage and is
  shared across components via a module-level ref.
- Groups become lockable via the same inline lock toggle. A locked
  group propagates to its children: they behave as effectively locked
  in the timeline and on the stage. Collapse/expand still works on a
  locked group.
- Canvas: layers in locked+hidden tracks render as a 1px outline in
  the layer (or fill) color instead of their full fill, and are
  draggable:false / listening:false. Mask layers keep their dashed
  ghost styling; masks still apply in the preview overlay regardless
  of lock or show state.
- drawSceneFrame gains an optional `{ crop }` option; the mask-preview
  overlay passes the editor's crop toggle through, so the two controls
  are fully independent. Crop changes now also trigger a preview
  redraw via a watcher dep.
- Tests: new suites for show-locked persistence, group lock store
  action, crop option on drawSceneFrame (including mask+crop combos).
  Properties transparent-toggle tests now reset the section prefs
  localStorage so the Appearance section is guaranteed open when the
  panel mounts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 16:42:39 +02:00
thandClaude Opus 4.7 cbc309bc8c 0.5.1: replace properties checkboxes with icon toggles
All checkboxes and radio buttons in the Properties panel are now
icon-toggle buttons:

- Polygon "Closed path" → PhPolygon button (fill weight when closed)
- Fill/Stroke transparent → PhEye / PhEyeSlash toggle next to the swatch
- Mask use → PhMaskHappy toggle
- Mask mode → segmented control with PhPlus / PhMinus (negative is red)

Shared .icon-toggle style: 26×26, panel background, accent when active,
optional .danger variant. Tests updated to click buttons instead of
checkboxes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:18:47 +02:00
thandClaude Opus 4.7 ddea7d348f 0.5.0: RUWIO rebrand, vertex bezier, animation paths, welcome focus
- Rename the app to RUWIO: title, APP_NAME, topbar logo (40px PNG),
  welcome dialog header and about dialog switch from the PhSparkle
  glyph to the real logo. Redundant name text next to the logo is
  removed across the board.
- About dialog: logo spans the full dialog width, the bottom Close
  button is gone (close via header X stays).
- Vertex bezier for polygons: each vertex can be Corner / Curve / Split
  curve via right-click. Curve mirrors tangent handles symmetrically,
  split curve keeps them independent. Tangents are fully animatable
  per keyframe — lerp mirrored across all four render pipelines.
- Stage path overlay: selecting a keyframe draws the tween arc between
  the previous and selected keyframe with draggable per-frame dots that
  curve the path via quadratic bezier control points. Other segments
  on the same track render as dashed ghost lines so the full curve is
  visible. Path dots grow + show grab cursor on hover.
- Vertex box-select: click-drag on empty stage while a polygon is
  selected boxes vertices. Shift-click toggles individual vertices
  into/out of the selection. Multi-vertex drag moves all selected at
  once; right-click on a selected vertex applies Corner/Curve/Split
  to all. Tangent handles only render when exactly one vertex is
  selected.
- Welcome dialog focus: opens with the most recent project focused.
  Enter opens it; Tab cycles only through the dialog's real buttons
  (delete icons pulled out of tab order, scrollable body removed from
  tab order). Export-current removed from welcome (not useful on
  startup).
- Modal focus trap: all modals now keep Tab inside the dialog.
- Fill / stroke transparency toggle restores the last real color when
  flipped back on, with a layer-base / asset fallback chain so there's
  always a visible color to restore to. A watcher keeps the restore
  cache in sync with the sampled value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 12:12:38 +02:00
thandClaude Opus 4.7 869b67458a 0.4.0: clipart drawer, animation paths, bezier keyframes
- Clipart library: new left-edge drawer (5px idle, expands on hover,
  400px when open). User picks a local folder via the File System Access
  API in settings; directory handle is persisted in IndexedDB so the
  library survives reloads. Dragging a thumbnail onto the stage creates
  an image asset + layer at the drop point.
- Animation paths on the stage: selecting a keyframe draws the tween
  path from the previous keyframe to the selected one as a solid
  polyline with per-frame draggable dots. All other segments on the
  same position-track render as dashed ghost lines so the full curve
  progression is visible.
- Path dots grow on hover (2.5 → 6 px), show a grab cursor, and have a
  wider hit area so they're easier to grab.
- Bezier-curved position interpolation: keyframes gain optional
  ctrlX/ctrlY fields. When set, x/y tween along a quadratic bezier
  through the control point instead of a straight line. Dragging a
  path dot solves for the control so the curve passes through the
  drag point at its frame progress. Mirrored across all four render
  pipelines.
- Tests: new suites for polygon actions, freeform drawing lifecycle,
  polygon + stroke rendering (15 new tests). Fixed the mask-render
  tests that relied on a default-transparent canvas background.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 10:35:43 +02:00
th 03b1147a93 bak 2026-04-20 01:05:27 +02:00
th 43933f93d1 bak 2026-04-20 00:29:12 +02:00
th 3ef5fb5a2d bak 2026-04-20 00:07:08 +02:00
th 6b6157d786 bak 2026-04-19 22:32:06 +02:00
th fcefd258eb bak 2026-04-19 21:40:09 +02:00
th b977ee35a8 bak 2026-04-19 21:13:53 +02:00
th cc6b11e61d bak 2026-04-19 20:31:53 +02:00
th e4aa0dce86 bak 2026-04-19 19:32:23 +02:00