Animated vector graphics for Rust

Animated SVG and Lottie in one Rust scene model.

dxn_vector_animation reads Figma Motion's animated SVG (CSS and SMIL), Lottie and dotLottie into one scene of groups, shapes and paints whose properties are keyframe tracks. Sample it into a display list, render it with the reference renderer, or play it: the NSH player maps the tracks onto NSH's native animation graph, so an animation runs on the UI thread on iOS, Android, macOS, Windows, Linux and the web.

[dependencies]
dxn_vector_animation = { git = "https://github.com/dXnSix/dXn.VectorAnimation", branch = "main" }
dxn_vector_animation_svg = { git = "https://github.com/dXnSix/dXn.VectorAnimation", branch = "main" }
Inputs
SVG (CSS, SMIL), Lottie, dotLottie
Rust
1.97+, edition 2024
Core targets
native and wasm32
Player
NSH, 7 platforms checked
Unsafe
forbidden
License
MIT OR Apache-2.0

Quick tour

#One model for two formats

An SVG and a Lottie file read into the same Scene: the importers differ, everything after them does not.

let svg = dxn_vector_animation_svg::read(&std::fs::read("loader.svg")?)?.scene;
let lottie = dxn_vector_animation_lottie::read(&std::fs::read("loader.json")?)?.scene;

for scene in [&svg, &lottie] {
    let frame = scene.frame_at(scene.timeline.duration / 2.0);
    println!("{} items half way", frame.items.len());
}

The scene’s nodes, paints and tracks are described in The scene model.

#Played on the UI thread

In an NSH app the VectorAnimation component plays a file natively. This is its web build, playing a Figma Motion export:

A Figma Motion SVG export, played by the NSH player in the browser.
import { VectorAnimation } from "dxn-vector-animation";
import button from "./button.vector-animation.json"; // compiled ahead with the CLI

<VectorAnimation src={button} style={{ width: 320, height: 160 }} paused={!active()} />

How a scene becomes canvases and graph nodes is in What it plays natively.

#Compile once, play anywhere

The CLI checks a file and compiles it into the scene format players load, with the importers out of the loop:

vector-animation validate --strict hero.svg
vector-animation compile hero.svg            # hero.vector-animation.json
vector-animation render hero.svg --fps 30 --width 600

The commands and their flags are in The vector-animation CLI.

#Effects and masks, live

Drop and inner shadows, blurs, soft masks and color effects play on the graph where it can express them, and frame by frame where it cannot:

Inner shadows whose offsets and colors move on the graph.

Every check scene is on the Examples page.