thandClaude Opus 4.7 80e1510b53 1.2.8: kaleidoscope — radial repeat for layers + clips with delayed-start arms
New per-entity property that renders content N times around a pivot.
For clip instances each radial copy can also be staggered in time, so
arm i starts playing the clip i*offset frames later than the source.

Data model (src/types/scene.ts):
- Layer: kaleido?, kaleidoCount?
- ClipInstance: kaleido?, kaleidoCount?, kaleidoOffset?, kaleidoRotateCopies?,
  kaleidoPivotX?, kaleidoPivotY?
All fields optional; legacy projects unchanged.

Math (src/lib/kaleido.ts):
- kaleidoCountFor / kaleidoAngleDegrees, clipKaleidoPivot, clipArmTranslate.
- clipArmLocalTime: returns the per-arm clip-local time. For arm i with
  offset dt, the arm shows frame (offsetIntoBlock - i*dt) — visible only
  when that falls inside [0, trimmedDuration]. Returns null otherwise so
  the caller can hide pre-start and post-end arms.

Render parity:
- src/lib/render.ts: extracted renderClipInstance helper used by both the
  top-level scene loop and drawTrackGroup. drawLayers + drawMaskShape now
  loop the kaleido count and add the per-copy angle to the layer rotation
  (Konva-style "rotate around (x,y)" comes for free).
- src/lib/exportPlayer.ts: mirror in JS (kalCount, kalAngle, clipKaleidoPivot,
  clipArmLocalT, clipArmTrans, drawClipInstance). drawLayer + drawMaskShape
  wrapped the same way. RUNTIME_VERSION 28 → 31 (3 fixes during landing).
- src/components/CanvasStage.vue: stackItems now emits one bundle per
  kaleido arm with arm-specific items sampled at the arm's localT, so the
  Konva live preview shows the staggered start in the editor — not just
  in the fullscreen preview / export. Source arm (armIndex 0) keeps the
  selection / drag / transform handlers; non-source arms are listening:
  false. New clipInstanceKaleidoGroupConfig handles the per-arm transform
  with rotateCopies on/off semantics. withK helper augments per-layer
  configs with the kaleido rotation.

UI (src/components/PropertiesPanel.vue + i18n):
- New "Kaleidoscope" collapsible section. Layer mode: toggle + repeat.
  Clip-instance mode (selected via canvas, panel banner explains the
  partial editability): toggle, repeat, start offset (frames — converted
  to seconds via scene.fps before storage), pivot X/Y, rotate-copies
  toggle. Hidden for button-asset layers (hit-area routing breaks if
  multiplied).

Store (src/stores/scene.ts):
- setLayerKaleido / setLayerKaleidoCount with [2, 64] integer clamp,
  setClipInstanceKaleido with clear-semantics for offset=0 and
  rotateCopies=true (deletes the field so JSON stays clean).

Tests (8 new under "kaleidoscope — store + render + engine"):
- Roundtrip + clamp for both Layer and ClipInstance setters.
- drawSceneFrame: 4 cardinal-pixel kaleido smoke for static layer.
- Button asset bypasses kaleido (hit-area routing intact).
- ClipInstance roundtrip + clear-semantics for offset=0.
- clipArmLocalTime: arm 0 honours bounds (returns null when source
  itself is past), delayed arms outlive the source's window when
  their shifted time is still in [0, dur].
- drawSceneFrame integration: 4-arm clip with 0.5s offset; sample at
  t=0 / t=0.5 / t=1.5 verifies staircase visibility (1 → 2 → 3 arms).
- Engine source carries kalCount, kalAngle, drawClipInstance,
  clipKaleidoPivot, clipArmLocalT; RUNTIME_VERSION '31'.
- layerActiveAt regression — kaleido fields don't break visibility gate.

Plus the prior export-runtime test updated to read drawClipInstance's
inst.{x,y,scaleX,scaleY,rotation} variables instead of the old inline
inst2.* names that the kaleido refactor removed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 19:18:16 +02:00
2026-04-23 19:33:22 +02:00
2026-04-19 17:53:36 +02:00
2026-04-19 17:53:36 +02:00
2026-04-25 00:40:53 +02:00
S
Description
No description provided
8.8 MiB
0 Stars 3 Watchers 0 Forks
Languages
TypeScript 60%
Vue 35.4%
JavaScript 3.4%
HTML 0.9%
CSS 0.2%
Other 0.1%