Skip to content

Latest commit

 

History

History
112 lines (77 loc) · 6.18 KB

File metadata and controls

112 lines (77 loc) · 6.18 KB

Back to Index

Vector Animation

Vector animation clips support Lottie and Rive as first-class media items. .lottie, Lottie JSON, and .riv files import into the Media panel, render through the same timeline/export pipeline as other clips, and expose clip-specific controls in the Properties panel.


Supported Sources

  • .lottie packages
  • Lottie JSON files when the JSON structure is positively identified as a Lottie animation
  • .riv Rive files via @rive-app/canvas

The import path does not treat arbitrary .json files as animation. Files are sniffed first, then promoted to type: 'lottie' only when the payload matches expected Lottie structure. Rive imports are extension-based and use type: 'rive'.


Timeline Behavior

  • Vector animation clips live on video tracks.
  • The clip bar shows an L badge for Lottie and an R badge for Rive.
  • naturalDuration, frame rate, dimensions, animation names, and other vector metadata are extracted during import.
  • Loop-enabled clips can be extended beyond their source duration on the right trim edge.
  • Copy/paste, nested compositions, slot decks, and background-layer playback preserve the clip type and vector animation settings.

Properties Panel

Vector animation clips add a dedicated provider tab in the unified Properties panel: Lottie for Lottie clips and Rive for Rive clips.

Current controls:

  • Loop toggle
  • End behavior: hold, clear, or loop
  • Playback mode: forward, reverse, bounce, or reverse-bounce
  • Fit: contain, cover, or fill
  • Render resolution override with fallback to the imported animation size
  • Rive artboard picker when the file exposes multiple artboards
  • Animation picker when the file exposes multiple animations
  • State Machine picker when the file exposes state machines
  • State override plus stepped state keyframes for discrete timeline-driven state changes
  • Boolean and numeric state-machine inputs as normal stopwatch keyframe properties
  • Rive view model and instance picker for Data Binding
  • Rive boolean, numeric, integer, and color Data Binding properties as stopwatch keyframe properties
  • Rive string and enum Data Binding properties as static clip settings
  • Background color override

The tab also shows the clip name plus imported width, height, and frame rate metadata when available.


Rendering

Runtime playback is split by provider and routed through src/services/vectorAnimation/VectorAnimationRuntimeManager.ts.

  • Lottie playback is driven by src/services/vectorAnimation/LottieRuntimeManager.ts.

  • Rive playback is driven by src/services/vectorAnimation/RiveRuntimeManager.ts using @rive-app/canvas.

  • Each clip gets a dedicated runtime canvas.

  • The runtime canvas can use the imported animation size or the clip-level render resolution override.

  • Timeline time is converted into a deterministic target frame rather than relying on autoplay.

  • Bounce modes are resolved in the timeline-time mapping, so preview and export render the same ping-pong frames.

  • If a state machine is selected, lottieState.{stateMachine} keyframes resolve the active state at the current timeline time before the frame is rendered.

  • If state-machine inputs are keyframed, the interpolated input values are applied before the frame is rendered.

  • Rive Data Binding values use riveData.{property} keyframes for numeric, boolean, integer, and color properties and are applied before draw.

  • Rive Events are subscribed through EventType.RiveEvent with automatic event side effects disabled. Events are logged for debugging rather than opening URLs or running implicit browser actions.

  • Rive runtime asset loading keeps the Rive CDN fallback enabled and leaves a custom asset-loader hook in place for future project-local asset resolution.

  • The runtime canvas is marked as dynamic, so TextureManager re-uploads it every frame instead of caching only the first frame.

  • The same canvas-backed source flows through preview, nested comps, slot/background playback, thumbnails, and export.

That shared path is the reason reloading at a different playhead position now shows the correct frame immediately, and why preview and export stay aligned.


Persistence And Reload

Saved data includes:

  • media-level vector metadata
  • clip-level vectorAnimationSettings
  • playback mode, render resolution, artboard, state machine selection, static state override, state keyframes, state-machine input values, view model selection, and Data Binding values
  • serialized timeline clip type lottie or rive
  • clipboard payloads and nested-composition clip data

On project load, the app restores vector animation metadata from project data and recreates the runtime from the file, the copied Raw/ media, or a recovered file handle.

If a retained File object still exists after refresh but the browser object URL is dead, the Media panel regenerates the missing URL and image/video thumbnail automatically.


Export

Vector animation export does not use a separate renderer.

  • The export layer builder asks the runtime for the correct frame at the current export time.
  • That frame is composited through the normal GPU path with effects, transforms, masks, nested comps, and other layers.
  • Output is rasterized into the final render like any other canvas-backed source.

This keeps vector animation clips aligned in fast preview, precise export, and image export.


Current Limits

  • Rive state machines use the public high-level WASM runtime. Input values are timeline-driven, but state-machine internal progression is limited by the high-level runtime API.
  • Boolean and numeric state-machine inputs are exposed as keyframe controls. String inputs are static for Lottie, and trigger/event inputs are not deterministic timeline controls yet.
  • Rive image/font/audio asset loading currently relies on embedded assets or the Rive CDN fallback. Project-local asset binding is a future extension point.
  • State selection uses stepped lottieState.{stateMachine} keyframes rather than bezier curves because named states are discrete strings.
  • Export output is rasterized; there is no vector-native export target.
  • If no Raw/ copy or file handle is available after reload, the clip still needs the normal relink flow.