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.8.0:
| Crate | Description | no_std |
|---|---|---|
animato-core |
Traits + 38 easing variants (5 advanced in v0.8.0) | ✅ |
animato-path |
Bezier, motion paths, MorphPath, DrawSvg (v0.8.0) |
core |
animato-driver |
AnimationDriver, Clocks, ScrollDriver, ScrollClock (v0.8.0) |
— |
| … all others unchanged … |
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.8"
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.8", = ["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.8", = ["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.8", = ["color"] }
use ;
let mut tween = new
.duration
.build;
tween.update;
let midpoint = tween.value.into_inner;
assert!;
Advanced Easing (v0.8.0)
Five new parameterised easing variants are now available:
use Easing;
// Organic, rough motion (deterministic)
let rough = RoughEase ;
// Fast at edges, crawls in the middle
let slow = SlowMo ;
// Oscillating wiggle (fades to zero at endpoints)
let wig = Wiggle ;
// Configurable bounce (0.0=linear, 1.0=EaseOutBounce)
let bounce = CustomBounce ;
// Exponential time warp
let expo = ExpoScale ;
// All satisfy: apply(0.0) == 0.0, apply(1.0) == 1.0
for e in &
Shape Morphing (v0.8.0)
[]
= { = "0.8", = ["path"] }
use ;
let square = vec!;
let circle: Vec =
.map
.collect;
let morph = with_resolution;
let mut tween = new.duration.build;
tween.update;
let shape = morph.evaluate; // Vec
SVG Draw Animation (v0.8.0)
use ;
let path = new;
let mut tween = new.duration.build;
tween.update; // halfway
let draw = path.draw_on;
println!;
// Or: draw.to_css()
Scroll-Linked Animation (v0.8.0)
use ;
// ScrollDriver approach
let mut driver = new;
driver.add;
driver.set_position; // 50% scroll → animations ticked by 0.5
// ScrollClock approach — works with AnimationDriver
let mut clock = new;
clock.set_scroll;
let dt = clock.delta; // 0.25
Feature Flags
[]
= { = "0.8", = ["serde"] }
v0.8.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.8", = false }
= { = "0.8", = false }
= { = "0.8", = false }
= { = "0.8", = false }
= { = "0.8", = false }
= { = "0.8", = 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
38 easing variants — 31 classic + CSS-compatible + 5 advanced (v0.8.0):
| Group | Variants |
|---|---|
| Linear | Linear |
| Polynomial | EaseIn/Out/InOut × Quad, Cubic, Quart, Quint (12) |
| Sinusoidal | EaseIn/Out/InOutSine |
| Exponential | EaseIn/Out/InOutExpo |
| Circular | EaseIn/Out/InOutCirc |
| Back | EaseIn/Out/InOutBack |
| Elastic | EaseIn/Out/InOutElastic |
| Bounce | EaseIn/Out/InOutBounce |
| CSS-compatible | CubicBezier(f32,f32,f32,f32), Steps(u32) |
| Advanced (v0.8.0) | RoughEase{…}, SlowMo{…}, Wiggle{…}, CustomBounce{…}, ExpoScale{…} |
| Escape hatch | Custom(fn(f32)->f32) |
Bevy Integration
Animato v0.8.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.8", = ["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.8.0 — Advanced shipped
| Next | Milestone |
|---|---|
v0.9.0 |
Performance — GPU batch compute, animato-gpu, benchmarks |
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.