Skip to content

Repository files navigation

🎞️ animate

Lightweight Rust animation library with tweening and physics-based springs

Demo

Features

  • Lightweight: Zero dependencies by default.
  • Ergonomic: Macro-driven API with minimal boilerplate.
  • Extensible: Many built-in types with support for custom interpolators.
  • Animation modes: once, cycle, alternate.
  • Easing: Built-in and custom easing functions.
  • Physics-based: Supports spring animations.
  • Ratatui-friendly: Interpolators for ratatui types, gated behind the ratatui feature flag.

Installation

cargo add animate

Getting started

Add #[animate] to a struct and mark the fields you want to animate:

#[animate]pubstructMyWidget{#[tween(duration = 300)]progress:f64,#[tween(mode = "cycle", duration = 400, easing = cubic_in)]color:Color,#[tween(mode = "alternate", duration = 500, easing = quad_in_out)]status:String,}

By default the macro generates an update method named animate. It must be called at the top of your struct's render method.

#[animate]pubstructMyWidget{ ... }implMyWidget{pubfndraw(&mutself,frame:&mutFrame){self.animate();// rest of your code}}

If the name conflicts with an existing method, rename it:

#[animate(update = "update_animations")]pubstructMyWidget{ ... }

Next, place animate::tick()before your struct's update call at the start of each frame:

letmut widget = MyWidget::new(...);loop{
animate::tick(tickrate);
terminal.draw(|frame| {
widget.draw(frame);})?;}

Use get() to read and set() to write animated fields.

Minimal example

use animate::animate;use std::{io::{stdout,Write}, thread, time::Duration};#[animate]structCounter{#[tween(duration = 400)]value:u32,}fnmain() -> std::io::Result<()>{letmut c = Counter::new(0);loop{
animate::tick(8);// advance global frame time by frame delta (ms)
c.animate();// update all animated fieldslet v = *c.value;if v == 0{
c.value.set(100);}print!("\rCounter value: {v}");stdout().flush()?;if v == 100{break;}
thread::sleep(Duration::from_millis(8));}Ok(())}

Animation modes

Mode valueBehaviour
"once"Animates to target once, then holds.
"cycle"Loops continuously from start to target.
"alternate"Ping-pongs back and forth between start and target.

Fields

#[tween(duration = 300, easing = quad_in_out, interp = my_interp_fn)]
OptionTypeDefaultDescription
durationu64 (ms)0Animation duration in milliseconds.
easingpathlinearEasing function (fn(f64) -> f64).
interppath<T as Lerp>::lerpInterpolation function (fn(&T, &T, f64) -> T).

Built-in easing functions

linear, quad_in, quad_out, quad_in_out, cubic_in, cubic_out, cubic_in_out

Spring animations

In addition to time-based animations, or Tweens, animate also supports physics-based spring animations.

#[animate]pubstructWidget{#[spring(stiffness = 200.0, damping = 20.0, mass = 1.0)]x:f64,}

Custom types

impl animate::TweenforMyColor{fnlerp(start:&Self,end:&Self,t:f64) -> Self{MyColor{r: u8::lerp(&start.r,&end.r, t),g: u8::lerp(&start.g,&end.g, t),b: u8::lerp(&start.b,&end.b, t),}}}

Releases

Packages

Contributors

Languages