The vector-animation CLI

The vector-animation command - inspect, validate, compile and render animated SVG, Lottie, dotLottie and compiled scenes - with every flag, its output and exit codes.

vector-animation reads any file the library reads and inspects it, checks it, compiles it into a scene or renders it to PNG. You reach for it in build scripts and CI, and to see what the library makes of a file before writing code.

cargo install --git https://github.com/dXnSix/dXn.VectorAnimation --branch main dxn_vector_animation_cli
vector-animation validate --strict hero.json

From a checkout, cargo run -p dxn_vector_animation_cli -- <command> runs it without installing.

CommandDoes
inspect <FILE>Prints the file’s size, timeline, contents and what it leaves out
validate [--strict] <FILE>Reads the file and reports whether it plays; fails on errors, and on warnings with --strict
compile [-o <OUTPUT>] [--pretty] <FILE>Writes the scene as a compiled .vector-animation.json
render [OPTIONS] <FILE>Renders frames as PNG images

Every command takes an animated SVG, a Lottie JSON, a dotLottie archive or a compiled scene, and tells them apart by their content, not their extension: a compiled scene first, then Lottie (a ZIP archive, or JSON that is not SVG), then SVG. Files are read with the default limits.

#inspect

vector-animation inspect lottie-motion.json
lottie-motion.json
  format       Lottie
  size         100 × 100
  timeline     2.000 s at 30 fps, loops
  marker       half at 1.000 s for 0.500 s
  nodes        6 groups, 3 shapes, 0 images (depth 4)
  animation    3 animated properties, 6 keyframes
  path points  0
  left out     nothing
LineShows
formatanimated SVG, Lottie or compiled scene
sizeThe scene’s width and height in user units
timelineDuration, frame rate when the file has one, and once, loops or ping-pong, with from <seconds> when the loop starts over after the start (1.400 s, loops from 0.400 s for a staggered loader)
markerEach named marker: start and duration
eventEach event the file plays something on, and the render flag that plays it
nodes, animation, path pointsThe scene’s Stats
left outEach warning, or nothing

An SVG whose button animates on begin="click" lists its event:

  event        btn.click: plays for 0.300 s (render --event btn.click=<seconds>)

#validate

vector-animation validate figma-motion.svg
vector-animation validate --strict foreign.svg
figma-motion.svg: valid animated SVG
warning: <foreignObject> is left out
foreign.svg: 1 warning(s)
FlagEffect
--strictFails when the file has any warning

Warnings are printed to stdout, one warning: line each. Without --strict a file with warnings is valid; with it, the command prints the count and exits with 1. A file that cannot be read prints error: <file>: <reason> to stderr and exits with 1:

error: broken.json: invalid file: no frame rate (`fr`)

#compile

vector-animation compile button.svg
vector-animation compile hero.json -o assets/hero.vector-animation.json --pretty
button.vector-animation.json
assets/hero.vector-animation.json
FlagDefaultEffect
-o, --output <OUTPUT>Next to the file, its extension replaced by .vector-animation.jsonWhere to write; - for stdout
--prettyoffIndented JSON

Warnings go to stderr, the path written to stdout. With -o - the scene itself goes to stdout instead, for a pipe:

vector-animation compile button.svg -o - | gzip > button.vector-animation.json.gz

A scene holding a number JSON cannot hold (NaN or an infinity) is not written: the command prints the error and exits with 1. The format is described in Compiled scenes.

#render

vector-animation render figma-motion.svg --time 0.5 --width 400 --background white
vector-animation render lottie-motion.json --fps 2
vector-animation render lottie-motion.json -t 0 -t 1 -o shots
figma-motion.png  t=0.500s
lottie-motion-frames/lottie-motion-0000.png  t=0.000s
lottie-motion-frames/lottie-motion-0001.png  t=0.500s
lottie-motion-frames/lottie-motion-0002.png  t=1.000s
lottie-motion-frames/lottie-motion-0003.png  t=1.500s
lottie-motion-frames/lottie-motion-0004.png  t=2.000s
shots/lottie-motion-0000.png  t=0.000s
shots/lottie-motion-0001.png  t=1.000s
FlagDefaultEffect
-t, --time <TIMES>0A time to render, in seconds; repeat it for several
--fps <FPS>Renders the timeline from 0 to its end every 1/FPS seconds (at most 100,001 frames); cannot be combined with --time
--width <WIDTH>Pixels wide; the height keeps the aspect unless given
--height <HEIGHT>Pixels high
--scale <SCALE>1Pixels per user unit when no size is given
--background <BACKGROUND>transparent#rrggbb, #rrggbbaa, white, black or transparent
--event <EVENTS>An event that happened, name=seconds; repeat it for several. What the file plays on it plays from then
-o, --output <OUTPUT>Next to the fileA PNG file for one frame, or a directory for several

Without -o, one frame goes to <stem>.png next to the file and several to a <stem>-frames/ directory there. An -o ending in .png is the file for a single frame; any other -o is a directory, created when missing. Frames in a directory are named <stem>-0000.png, <stem>-0001.png and so on. Each line printed is a file and the time it shows.

Times are rendered as given, not wrapped into the loop: --fps renders one play-through, what comes before the loop start once and the loop once. A --time past the end of a timeline that loops is rendered all the same (an animated SVG’s tracks run on for a second loop and then hold their last values, a Lottie layer ends at its out point) and the command warns on stderr, naming the time the player shows there: vector-animation render alien-button.svg -t 12.5 warns that the player shows 0.500 s, and -t 0.5 is the frame to render. --event moves what the file plays on an event to that time, as Scene::with_events does:

vector-animation render press.svg --event btn.click=0.5 -t 0.6 -o pressed.png

Rendering uses the reference renderer, so live text is set in the machine’s fonts and images over 8192 × 8192 pixels are refused.

#Exit codes

CodeWhen
0Success
1The file could not be read or written, a flag value was invalid (--fps 0, --event bad, an unknown color), or validate --strict found warnings
2The command line itself is wrong: an unknown flag, a missing file argument, --fps with --time

Errors are printed to stderr as error: <message>.

Next: Compiled scenes, or Untrusted input for the limits every command reads within.