Domotion

Animation model

Frames, transitions, overlays — how multi-frame SVGs are composed.

An animated Domotion SVG is several captured frames stitched together with CSS keyframes. There's no JavaScript at runtime — the browser plays the animation natively from the SVG's embedded <style>. This page explains the model so you know what's possible and where the seams are.

The frame

An animation frame is a single capture (the svgContent returned from elementTreeToSvg) plus timing and an optional transition to the next frame:

interface AnimationFrame {
  svgContent: string;          // from elementTreeToSvg()
  duration: number;             // hold time in ms
  transition?: {
    type: "crossfade" | "push-left" | "scroll";
    duration: number;
  };
  overlays?: Overlay[];        // typing, tap ripples
}

You build a list of frames and pass them to generateAnimatedSvg(config). The result is one SVG with one @keyframes rule per frame and per overlay, summed timeline, infinite loop.

Three transition types

TypeBehaviorBest for
crossfade Outgoing frame fades to 0 while incoming frame fades to 1, with overlap so shared pixels stay visible. State changes within the same screen (form being filled, list updating).
push-left Outgoing frame slides off to the left, incoming slides in from the right. Stepping through a flow ("step 1 → step 2 → step 3").
scroll Both frames stay visible; opacity transitions only at the very end. Scrolling content, where one frame logically continues into the next.

Crossfade is the smart path

When every transition in a sequence is crossfade (or unset), Domotion takes a fast path: it merges all frames into one de-duplicated element tree with per-element visibility timelines. Stable elements — a static logo, a header that doesn't change — are emitted once with opacity: 1 throughout. Changing elements get step-end keyframes that flip them on at the right moment.

Two payoffs:

  1. No flicker. Without merging, naive cross-fades would redraw every static pixel on every transition; small CSS-paint glitches at the boundary cause a one-frame dark flash. Merged frames just don't redraw those pixels.
  2. Smaller files. The text "Hello" doesn't appear five times in the SVG — once, with a timeline saying when it's visible.

push-left and scroll can't merge because the geometry of each frame is different at every instant; they fall back to the "emit each frame as a clipped group" path.

Overlays

Overlays sit on top of a frame's content for the duration of that frame. Two kinds today:

  • typing — animates a string being typed character-by-character at a given coordinate. Useful for terminal demos and "user types into a search box" patterns.
  • tap — a Material-style ripple at a coordinate, suggesting a click or tap. Useful for "user clicks here" cues on mobile demos.

See the Typing & tap overlays guide for working examples.

Shared definitions

Glyph paths, gradient defs, and clip paths can be expensive when repeated across frames. generateAnimatedSvg accepts a sharedDefs string — markup that gets hoisted into the top-level <defs> so frames can reference IDs across the animation. The simplest pattern is to capture all frames first, then pull their glyph defs out and pass them as sharedDefs; the test runners and example scripts do exactly this.

Loop semantics

The generated animation always loops infinitely with animation: ... infinite. Single-shot playback is not supported in SVG without scripting. If you need playback control, embed the SVG via <object> and toggle a CSS class on the host page, or wrap your captures in a JavaScript controller.

Browser support

The output uses standard CSS keyframes and SMIL-free SVG, supported in every modern browser. The same SVG renders in WebKit (Safari, iOS), Gecko (Firefox), and Blink (Chrome, Edge). It also renders in image contexts (<img>, background-image) — though some image contexts mute animations; embed via <object> or <iframe> if you find an environment that does.

Next

That's the model. Move on to the Build an animated demo guide for a runnable end-to-end recipe.