Italian: animato — animated, lively, with life and movement.
A professional-grade, renderer-agnostic animation library for Rust.
Zero mandatory dependencies. no_std-ready. Built as a clean Cargo workspace — use only the crates you need.
Works everywhere: TUIs, Web (WASM), Bevy games, embedded targets, CLI tools, and native desktop apps.
Why Animato?
Most Rust animation crates are either too minimal (just easing functions) or too coupled to a specific renderer or framework. Animato sits in between:
- Computes values, never renders. You own the render loop; Animato just tells you what the value is at each frame.
- Workspace architecture. Each concern lives in its own crate. You don't download
wgpujust to animate a progress bar. no_stdcore. The trait system, all easing functions,Tween<T>, andSpringcompile withoutstdor heap allocation.- Builder pattern everywhere. No positional argument confusion; every optional field has a sensible default.
- Generic over your types. Implement
Interpolateonce and animate any value —f32,[f32; 3], your custom color type, anything.
Crates
Shipped in v0.7.0:
| Crate | Description | no_std |
|---|---|---|
animato-core |
Traits (Interpolate, Animatable, Update, Playable) + 33 easing variants |
yes |
animato-tween |
Tween<T>, KeyframeTrack<T>, Loop, TweenState, TweenBuilder |
alloc |
animato-timeline |
Timeline, Sequence, stagger, callbacks, time scale, async wait |
alloc |
animato-spring |
Spring, SpringN<T>, SpringConfig presets |
✅ |
animato-path |
Bezier curves, CatmullRom splines, motion paths, SVG path parsing | core no_std |
animato-physics |
Inertia, DragState, GestureRecognizer, pinch, rotation |
core no_std |
animato-color |
Perceptual color interpolation in Lab, Oklch, and linear-light sRGB | yes |
animato-driver |
AnimationDriver, Clock, WallClock, MockClock |
— |
animato-bevy |
AnimatoPlugin, Bevy tween/spring components, completion messages |
— |
animato-wasm |
RafDriver, FLIP, SplitText, ScrollSmoother, Draggable, Observer |
— |
animato |
Facade crate — re-exports all of the above | — |
Planned in future versions (see ROADMAP.md):
| Crate | Version | Description |
|---|---|---|
animato-gpu |
v0.9.0 | GpuAnimationBatch — 10K+ tweens per frame on GPU |
Most users only need the facade:
[]
= "0.7"
Quick Start
Animate a single value
use ;
let mut tween = new
.duration
.easing
.build;
// In your update loop — pass dt (seconds since last frame):
tween.update; // ~60fps tick
println!; // current interpolated value
Spring physics
use ;
let mut spring = new;
spring.set_target;
// Animate until settled:
while !spring.is_settled
println!;
Loop modes
use ;
let mut tween = new
.duration
.easing
.looping
.build;
for _ in 0..600
println!; // oscillates 0 ↔ 100
AnimationDriver — manage many animations
use ;
let mut driver = new;
let mut clock = new;
let id = driver.add;
loop
Multi-dimensional spring
use ;
let mut spring: = new;
spring.set_target;
while !spring.is_settled
let = spring.position;
Keyframe tracks
use ;
let mut track = new
.push_eased
.push;
track.update;
assert!;
Timeline composition
use ;
let fade = new.duration.build;
let slide = new.duration.build;
let mut timeline = new
.add
.add;
timeline.play;
timeline.update;
assert_eq!;
Timeline control
use ;
let fade = new.duration.build;
let mut timeline = new
.add
.time_scale
.on_entry_complete
.on_complete;
timeline.play;
timeline.update;
assert_eq!;
With the tokio feature, timeline.wait().await resolves when another task or loop drives the timeline to completion.
Motion paths
[]
= { = "0.7", = ["path"] }
use ;
let curve = new;
let mut motion = new
.duration
.easing
.auto_rotate
.build;
motion.update;
let = motion.value;
let rotation = motion.rotation_deg;
Input physics
[]
= { = "0.7", = ["physics"] }
use ;
let mut inertia = new;
inertia.kick;
while inertia.update
let mut drag = new
.constraints;
drag.on_pointer_down;
drag.on_pointer_move;
let maybe_inertia = drag.on_pointer_up;
let mut gestures = default;
gestures.on_pointer_down;
let gesture = gestures.on_pointer_up;
assert!;
Color interpolation
[]
= { = "0.7", = ["color"] }
use ;
let mut tween = new
.duration
.build;
tween.update;
let midpoint = tween.value.into_inner;
assert!;
Feature Flags
[]
= { = "0.7", = ["serde"] }
v0.7.0 features:
| Feature | What it adds |
|---|---|
default |
std + tween + timeline + spring + driver |
std |
Wall clock, heap-backed composition types, timeline callbacks |
tween |
Tween<T>, KeyframeTrack<T>, Loop, TweenState |
timeline |
Timeline, Sequence, stagger, time scale |
spring |
Spring, SpringN<T>, all presets |
path |
QuadBezier, CubicBezierCurve, CatmullRomSpline, MotionPathTween, SvgPathParser |
physics |
Inertia, InertiaN<T>, DragState, GestureRecognizer |
color |
InLab<C>, InOklch<C>, InLinear<C>, and the palette re-export |
driver |
AnimationDriver, Clock variants |
bevy |
AnimatoPlugin, AnimatoTween<T>, AnimatoSpring<T>, transform helpers, completion messages |
wasm |
RafDriver + ScrollSmoother |
wasm-dom |
DOM helpers: FlipAnimation, SplitText, Draggable, Observer |
serde |
Serialize/Deserialize on supported concrete public types |
tokio |
.wait().await on Timeline completion |
Features planned for future versions:
| Feature | Version | What it adds |
|---|---|---|
gpu |
v0.9.0 | GpuAnimationBatch via wgpu |
no_std usage
[]
= { = "0.7", = false }
= { = "0.7", = false }
= { = "0.7", = false }
= { = "0.7", = false }
= { = "0.7", = false }
= { = "0.7", = false }
Available in no_std: Easing, Tween<T>, Spring, fixed Bezier curves, Inertia, GestureRecognizer, InLab<C>, InOklch<C>, InLinear<C>, and all Interpolate blanket impls. KeyframeTrack<T>, Timeline, SpringN<T>, MotionPath, SVG parsing, InertiaN<T>, and DragState require allocation.
Easing Functions
33 easing variants are available as Easing::EaseOutCubic (enum) or ease_out_cubic(t) (free function where applicable):
| Group | Variants |
|---|---|
| Linear | Linear |
| Polynomial | EaseIn/Out/InOut × Quad, Cubic, Quart, Quint (12 total) |
| Sinusoidal | EaseIn/Out/InOutSine |
| Exponential | EaseIn/Out/InOutExpo |
| Circular | EaseIn/Out/InOutCirc |
| Back (overshoot) | EaseIn/Out/InOutBack |
| Elastic | EaseIn/Out/InOutElastic |
| Bounce | EaseIn/Out/InOutBounce |
| CSS-compatible | CubicBezier(f32, f32, f32, f32), Steps(u32) |
| Escape hatch | Custom(fn(f32) -> f32) |
Additional advanced variants (RoughEase, SlowMo, Wiggle, CustomBounce, ExpoScale) remain planned for v0.8.0.
Bevy Integration
Animato v0.7.0 targets Bevy 0.18.1. The workspace MSRV is Rust 1.89 to match Bevy's published requirement.
use *;
use ;
use ;
WASM Integration
[]
= { = "0.7", = ["wasm"] }
use *;
use ;
Build: wasm-pack build --target web --features wasm
Architecture
Animato is a focused Cargo workspace with additional planned crates through v1.0. See ARCHITECTURE.md for the full design document — crate boundaries, module specifications, type system design, data flow diagrams, and performance guidelines.
Examples
# WASM:
# cd examples/wasm_counter && wasm-pack build --target web
Running Tests
# All tests, all features:
# no_std check:
# Benchmarks:
# Docs:
Roadmap
See ROADMAP.md for the full versioned plan from v0.1.0 to v1.0.0.
Current status: v0.7.0 — Integrations shipped
| Next | Milestone |
|---|---|
v0.8.0 |
Advanced — shape morphing, scroll-linked animation, FLIP layout |
Contributing
Contributions are welcome — bug reports, feature suggestions, documentation improvements, and pull requests.
See CONTRIBUTING.md for how to set up the workspace, run tests, and submit a PR.
Support
If Animato is useful to you, consider supporting ongoing development:
- ⭐ Star the repo on GitHub
- ☕ Buy Me a Coffee
- 💖 GitHub Sponsors
License
Licensed under either of:
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project shall be dual-licensed as above, without any additional terms or conditions.