Skip to content

The model

  • A component is a props struct. ui.show(component) renders it at the current time and returns an Svgr, so it goes anywhere {expr} is allowed in svgr!.
  • Build a Ui once at the top of render_frame: Ui::new(frame, ctx, &self.theme) in a video, Ui::for_scene(frame, ctx, &self.theme, self) in a scene. Scenes get the video’s context, so only for_scene knows the scene’s length that exit animations end with.
  • Time is local. A component has no start time. Its parent places it with a Sequence { from, duration, children }; inside, ui.seconds() starts at 0 and ui.duration is the sequence’s length in frames. Sequences nest and their offsets add up.
  • Props are plain data: numbers, &str/String, Color, Transform, enums, Option, Anim<T> (a fixed value or a stored timeline!) and children closures.
  • Defaults come from the theme: set what you need and finish with ..ui.defaults().
  • SVG ids (clip paths, gradients, filters) come from ui.id(key, index, kind): from a key: Option<&str> prop when given, else from the item index. Never from a counter.
  • Children are a closure that receives the container’s own Ui: children(|ui| ...).
use fframes_kit::prelude::*;
fn card<'a>(ui: &mut Ui<'a, '_, '_>) -> Svgr<'a> {
let fade = FadeIn { shift: (0.0, -40.0), delay: 0.2, ..ui.defaults() };
let accent = ui.theme.colors.accent;
fade.apply(ui, svgr!(<rect x="100" y="100" width="400" height="200" fill={accent} />))
}
fn layout<'a>(ui: &mut Ui<'a, '_, '_>) -> Svgr<'a> {
// `card` starts at 1s and lasts 3s; inside it, time starts at 0
ui.show(Sequence { from: 1.0, duration: Some(3.0), children: children(card) })
}