Expand description
§tween
tween
is an std-optional tweening library, designed for use in games and animations.
§Quick Start
To install, add the following to your Cargo.toml:
tween = "2.1.0"
You can make a Tweener, like this:
use tween::Tweener;
let (start, end) = (0, 100);
let duration = 15.0;
let mut tweener = Tweener::sine_in_out(start, end, duration);
let mut position = 0;
const DT: f32 = 1.0 / 60.0;
// and then in your main loop...
loop {
position = tweener.move_by(DT);
if tweener.is_finished() {
break;
}
}
assert_eq!(position, 100, "we've moved to the end of the tween");
§Overview
A Tween
is a function which returns values from one specified number to another specified number over a specified amount of time. The simplest Tween
which everyone is familiar with is lerp
, or “linear interpolation”. In this library, it is called Linear
– a Linear Tween moves from its start to its end by the formula start * (1.0 - p) + end * p
, where p
is the percent over time you are into the tween. So at time 0
, or 0%
, you end up with the start
value, and at time 1
, or 100%
, you end up with the end value.
There are many kinds of Tweens beyond Linear, of course; all of which can produce feel and animations! We often use tweens to move positions of objects in games, but you can use Tweens for animating a sprite, selecting behavior, audio manipulation, or even drawing fonts with Cubic Bezier Tweens.
This library gives you access to all the tweens initially made by Robert Penner – you can see them in action here.
This library exposes three kinds of structs:
- Zero-Sized Tweens which implement the
Tween
trait. They also expose the methodtween
inherently, so you can tween easily with them, liketween::Linear.tween
. - Wrapper Tweens which implement the
Tween
trait. These areLooper
,Oscillator
andExtrapolator
. These all wrap around other Tweens. See their documentation for more information. Tweener
andFixedTweener
, both of which “drive” aTween
. You should useFixedTweener
in a fixed timestep application; otherwise, useTweener
. Although you can use aTween
directly, aTweener
manages all the Tween state for you.
For 99% of users, you’ll want to construct Tweener
s or FixedTweener
s with a Tween for this library, occasionally looping or oscillating them.
§Making Tweens Yourself
If you’d like to make your own tween, you absolutely can! For that, you’ll need to see the main trait of this library: Tween
. You can prototype your own Tween
implementations with a simple closure, since FnMut(value_delta: Value, percent: f32) -> Value
implements Tween
, or just use that yourself. Closures are very nice because you can add, or even composite, tweens in interesting ways.
For example, here’s a Linear
tween averaged with a SineIn
tween:
use tween::{Tweener, SineIn, Linear};
Tweener::new(0.0, 10.0, 10, |value_delta, percent| {
(Linear.tween(value_delta, percent) + SineIn.tween(value_delta, percent)) / 2.0
});
To see a documented example of a Cubic Bezier Tween, see examples/cubic_bezier.rs
.
§Storing Tweens
Very often in a game or animation engine, you’ll want to store Tweens by what they act on, without caring about what kind of Tween example it is. To do that, you’ll want to box the Tween within the Tweener. Since all the Tweens in this library are ZSTs, the Box won’t actually allocate, though you will have to use dynamic access (which will be more than fast enough).
use tween::{Tweener, Looper, Linear, SineIn, Tween};
// very often game engines need sync/sync
type SendSyncTween<Value, Time> = Tweener<Value, Time, Box<dyn Tween<Value> + Send + Sync>>;
let mut my_tweener: SendSyncTween<i32, i32> = Tweener::new(0, 100, 100, Box::new(Linear));
let mut going_up = true;
// we lerp from 0 to 100 over 100 frames, and then we flip our tween back
// into a SineIn tween over 10 frames, so this looks like a slowwwwwww buildup
// and then a SHARP drop down.
//
// we put this in a thread here to demonstrate `Send + Sync`
std::thread::spawn(move || {
loop {
let _output_assigned_somewhere = my_tweener.move_by(1);
if my_tweener.is_finished() {
my_tweener = if going_up {
Tweener::new(100, 0, 10, Box::new(SineIn))
} else {
Tweener::new(0, 100, 100, Box::new(Linear))
};
going_up = !going_up;
}
}
});
To see a documented example of erased Tweeners, see examples/erased.rs
.
§Implementing TweenValue
This library uses two traits: TweenTime
and TweenValue
. You can implement these yourself, but implementing TweenTime
would only have fairly obscure uses.
On the other hand, TweenValue
needs to be implemented for any tweenable value. By default, all numerical types are already implemented in this library. Additionally, several math libs have a feature flag (see below) which gates an implementation for their structs as appropriate.
§Going Fast ⚡️
This library is, ultimately, a math library, and benefits enormously from being in release mode.
§Features
tween
has the following features:
std
: enabled by default, gives access to faster floating point math and helper methods withBox
libm
: enable this, without default features, for no-std tweeningglam
: enable this forglam
types to implementTweenValue
nalgebra
: enable this fornalgebra
types to implementTweenValue
§Std Optional
This library uses std
with the default feature std
. Disable default features, and enable libm
, for a no-std experience. (We need to use libm
for the floating point math), like so:
tween = { verison = "2.1.0", default_features = false, features = ["libm"] }
§MSRV and Safety
This crate has no MSRV yet. If it sees good adoption, an MSRV policy will be decided.
Additionally, this crate is #![deny(unsafe_code)]
, since no unsafe code was needed. Changing this policy would constitute a minor breaking change.
§Breaking Changes
This crate follows normal rules for breaking changes except for math libraries besides glam
. We make no promises that we’ll update perfectly with math libraries – you are encouraged to make forks of this repo instead if you have version handling requirements.
§Roadmap
Next up for this library is handling Splines of Tweeners.
§License
Dual-licensed under MIT or APACHE 2.0.
Structs§
- BackIn
- A tween that goes out and then back in a bit. Go here for a visual demonstration.
- Back
InOut - A tween that goes out, in, and then back in and out a bit. Go here for a visual demonstration.
- BackOut
- A tween that goes in and then back out a bit. Go here for a visual demonstration.
- Bounce
In - A bouncy tween, similar to gravity. Go here for a visual demonstration.
- Bounce
InOut - A bouncy tween, similar to gravity. Go here for a visual demonstration.
- Bounce
Out - A bouncy tween, similar to gravity. Go here for a visual demonstration.
- CircIn
- A circular tween in. Go here for a visual demonstration.
- Circ
InOut - A circular tween in and out. Go here for a visual demonstration.
- CircOut
- A circular tween out. Go here for a visual demonstration.
- CubicIn
- A cubic tween in. Go here for a visual demonstration.
- Cubic
InOut - A cubic tween in and out. Go here for a visual demonstration.
- Cubic
Out - A cubic tween out. Go here for a visual demonstration.
- Elastic
In - An elastic tween in. Go here for a visual demonstration.
- Elastic
InOut - An elastic tween in and out. Go here for a visual demonstration.
- Elastic
Out - An elastic tween out. Go here for a visual demonstration.
- ExpoIn
- An exponenential tween in. See here
- Expo
InOut - An exponenential tween in and out. See here
- ExpoOut
- An exponenential tween out. See here
- Extrapolator
- An Extrapolator is a wrapper around a Tween, which allows a tween to go beyond the range of
0.0
to1.0
. Note that for Looper, Oscillator, or any Tween whose Tween::is_finite returns false, wrapping in an Extrapolator is unnecssary, as they are already infinite tween. - Fixed
Tweener - A FixedTweener is a Tweener wrapper which implements Iterator. To do this, it takes a “fixed” delta on its constructor.
- Linear
- A Linear tween is a simple lerp from one value to another.
- Looper
- A Looper is a wrapper around a Tween, which makes it so that every time the tweener would fuse (end), it loops from the start.
- Oscillator
- An Oscillator is a wrapper around a Tween which places the Tween into an infinite ping pong.
- QuadIn
- An quadratic tween in. Go here for a visual demonstration.
- Quad
InOut - An quadratic tween in and out. Go here for a visual demonstration.
- QuadOut
- An quadratic tween out. Go here for a visual demonstration.
- QuartIn
- An quartic tween in. Go here for a visual demonstration.
- Quart
InOut - An quartic tween in and out. Go here for a visual demonstration.
- Quart
Out - An quartic tween out. Go here for a visual demonstration.
- QuintIn
- An quintic tween in. Go here for a visual demonstration.
- Quint
InOut - An quintic tween in out. Go here for a visual demonstration.
- Quint
Out - An quintic tween out. Go here for a visual demonstration.
- SineIn
- An sine based tween in. Go here for a visual demonstration.
- Sine
InOut - An sine based tween in out. Go here for a visual demonstration.
- SineOut
- An sine based tween out. Go here for a visual demonstration.
- Tweener
- A Tweener is a wrapper around a Tween. Although you can tween dynamically using just a raw Tween, this struct will manage state and allow for more naturalistic handling.
Enums§
- Current
Time State - This enum indicates a Tweener or FixedTweener’s current state.
It returns
Waiting
is the current time is less than 0,Finished
if it’s at the duration of the Tweener or greater, and valid otherwise.
Traits§
- Tween
- This is the core trait of the Library, which all tweens implement.
- Tween
Time - A
TweenTime
is a representation of Time. The two most common will bef32
/f64
for seconds andu32
/u64
/usize
for frames. - Tween
Value - A
TweenValue
is a value which can be Tweened. The library fundamentally outputsTweenValue
eventually.