pub struct Anim<F>(pub F);
Expand description
Anim
is the main type provided by pareen. It is a wrapper around any type
implementing Fun
.
Anim
provides methods that transform or compose animations, allowing
complex animations to be created out of simple pieces.
Tuple Fields§
§0: F
Implementations§
source§impl<F> Anim<F>where
F: Fun,
impl<F> Anim<F>where F: Fun,
sourcepub fn map<W>(self, f: impl Fn(F::V) -> W) -> Anim<impl Fun<T = F::T, V = W>>
pub fn map<W>(self, f: impl Fn(F::V) -> W) -> Anim<impl Fun<T = F::T, V = W>>
Transform an animation so that it applies a given function to its values.
Example
Turn (2.0 * t)
into (2.0 * t).sqrt() + 2.0 * t
:
let anim = pareen::prop(2.0f32).map(|value| value.sqrt() + value);
assert_approx_eq!(anim.eval(1.0), 2.0f32.sqrt() + 2.0);
sourcepub fn map_time<S>(
self,
f: impl Fn(S) -> F::T
) -> Anim<impl Fun<T = S, V = F::V>>
pub fn map_time<S>( self, f: impl Fn(S) -> F::T ) -> Anim<impl Fun<T = S, V = F::V>>
Transform an animation so that it modifies time according to the given function before evaluating the animation.
Example
Run an animation two times slower:
let anim = pareen::cubic(&[1.0, 1.0, 1.0, 1.0]);
let slower_anim = anim.map_time(|t: f32| t / 2.0);
pub fn map_anim<W, G, A>(self, anim: A) -> Anim<impl Fun<T = F::T, V = W>>where G: Fun<T = F::V, V = W>, A: Into<Anim<G>>,
pub fn map_time_anim<S, G, A>(self, anim: A) -> Anim<impl Fun<T = S, V = F::V>>where G: Fun<T = S, V = F::T>, A: Into<Anim<G>>,
pub fn into_fn(self) -> impl Fn(F::T) -> F::V
source§impl<F> Anim<F>where
F: Fun,
F::T: Clone,
impl<F> Anim<F>where F: Fun, F::T: Clone,
sourcepub fn zip<G, A>(self, other: A) -> Anim<impl Fun<T = F::T, V = (F::V, G::V)>>where
G: Fun<T = F::T>,
A: Into<Anim<G>>,
pub fn zip<G, A>(self, other: A) -> Anim<impl Fun<T = F::T, V = (F::V, G::V)>>where G: Fun<T = F::T>, A: Into<Anim<G>>,
Combine two animations into one, yielding an animation having pairs as the values.
pub fn bind<W, G>( self, f: impl Fn(F::V) -> Anim<G> ) -> Anim<impl Fun<T = F::T, V = W>>where G: Fun<T = F::T, V = W>,
source§impl<F> Anim<F>where
F: Fun,
F::T: Clone + PartialOrd,
impl<F> Anim<F>where F: Fun, F::T: Clone + PartialOrd,
sourcepub fn switch<G, A>(
self,
self_end: F::T,
next: A
) -> Anim<impl Fun<T = F::T, V = F::V>>where
G: Fun<T = F::T, V = F::V>,
A: Into<Anim<G>>,
pub fn switch<G, A>( self, self_end: F::T, next: A ) -> Anim<impl Fun<T = F::T, V = F::V>>where G: Fun<T = F::T, V = F::V>, A: Into<Anim<G>>,
Concatenate self
with another animation in time, using self
until
time self_end
(non-inclusive), and then switching to next
.
Examples
Switch from one constant value to another:
let anim = pareen::constant(1.0f32).switch(0.5f32, 2.0);
assert_approx_eq!(anim.eval(0.0), 1.0);
assert_approx_eq!(anim.eval(0.5), 2.0);
assert_approx_eq!(anim.eval(42.0), 2.0);
Piecewise combinations of functions:
let cubic_1 = pareen::cubic(&[4.4034, 0.0, -4.5455e-2, 0.0]);
let cubic_2 = pareen::cubic(&[-1.2642e1, 2.0455e1, -8.1364, 1.0909]);
let cubic_3 = pareen::cubic(&[1.6477e1, -4.9432e1, 4.7773e1, -1.3818e1]);
// Use cubic_1 for [0.0, 0.4), cubic_2 for [0.4, 0.8) and
// cubic_3 for [0.8, ..).
let anim = cubic_1.switch(0.4, cubic_2).switch(0.8, cubic_3);
sourcepub fn surround<G, A>(
self,
range: RangeInclusive<F::T>,
surround: A
) -> Anim<impl Fun<T = F::T, V = F::V>>where
G: Fun<T = F::T, V = F::V>,
A: Into<Anim<G>>,
pub fn surround<G, A>( self, range: RangeInclusive<F::T>, surround: A ) -> Anim<impl Fun<T = F::T, V = F::V>>where G: Fun<T = F::T, V = F::V>, A: Into<Anim<G>>,
Play self
in time range range
, and surround
outside of the time range.
Examples
let anim = pareen::constant(10.0f32).surround(2.0..=5.0, 20.0);
assert_approx_eq!(anim.eval(0.0), 20.0);
assert_approx_eq!(anim.eval(2.0), 10.0);
assert_approx_eq!(anim.eval(4.0), 10.0);
assert_approx_eq!(anim.eval(5.0), 10.0);
assert_approx_eq!(anim.eval(6.0), 20.0);
source§impl<F> Anim<F>where
F: Fun,
F::T: Copy + PartialOrd + Sub<Output = F::T>,
impl<F> Anim<F>where F: Fun, F::T: Copy + PartialOrd + Sub<Output = F::T>,
sourcepub fn seq<G, A>(
self,
self_end: F::T,
next: A
) -> Anim<impl Fun<T = F::T, V = F::V>>where
G: Fun<T = F::T, V = F::V>,
A: Into<Anim<G>>,
pub fn seq<G, A>( self, self_end: F::T, next: A ) -> Anim<impl Fun<T = F::T, V = F::V>>where G: Fun<T = F::T, V = F::V>, A: Into<Anim<G>>,
Play two animations in sequence, first playing self
until time
self_end
(non-inclusive), and then switching to next
. Note that
next
will see time starting at zero once it plays.
Example
Stay at value 5.0
for ten seconds, then increase value proportionally:
let anim_1 = pareen::constant(5.0f32);
let anim_2 = pareen::prop(2.0f32) + 5.0;
let anim = anim_1.seq(10.0, anim_2);
assert_approx_eq!(anim.eval(0.0), 5.0);
assert_approx_eq!(anim.eval(10.0), 5.0);
assert_approx_eq!(anim.eval(11.0), 7.0);
pub fn seq_continue<G, A, H>( self, self_end: F::T, next_fn: H ) -> Anim<impl Fun<T = F::T, V = F::V>>where G: Fun<T = F::T, V = F::V>, A: Into<Anim<G>>, H: Fn(F::V) -> A,
source§impl<F> Anim<F>where
F: Fun,
F::T: Copy,
F::V: Copy + Num,
impl<F> Anim<F>where F: Fun, F::T: Copy, F::V: Copy + Num,
sourcepub fn scale_min_max(
self,
min: F::V,
max: F::V
) -> Anim<impl Fun<T = F::T, V = F::V>>
pub fn scale_min_max( self, min: F::V, max: F::V ) -> Anim<impl Fun<T = F::T, V = F::V>>
Given animation values in [0.0 .. 1.0]
, this function transforms the
values so that they are in [min .. max]
.
Example
let min = -3.0f32;
let max = 10.0;
let anim = pareen::id().scale_min_max(min, max);
assert_approx_eq!(anim.eval(0.0f32), min);
assert_approx_eq!(anim.eval(1.0f32), max);
source§impl<F> Anim<F>where
F: Fun,
F::V: Float,
impl<F> Anim<F>where F: Fun, F::V: Float,
source§impl<F> Anim<F>where
F: Fun,
F::T: Copy + FloatCore,
impl<F> Anim<F>where F: Fun, F::T: Copy + FloatCore,
sourcepub fn squeeze(
self,
range: RangeInclusive<F::T>
) -> Anim<impl Fun<T = F::T, V = F::V>>
pub fn squeeze( self, range: RangeInclusive<F::T> ) -> Anim<impl Fun<T = F::T, V = F::V>>
Transform an animation in time, so that its time [0 .. 1]
is shifted
and scaled into the given range
.
In other words, this function can both delay and speed up or slow down a given animation.
Example
Go from zero to 2π in half a second:
// From zero to 2π in one second
let angle = pareen::circle::<f32, f32>();
// From zero to 2π in time range [0.5 .. 1.0]
let anim = angle.squeeze(0.5..=1.0);
assert_approx_eq!(anim.eval(0.5), 0.0);
assert_approx_eq!(anim.eval(1.0), std::f32::consts::PI * 2.0);
sourcepub fn squeeze_and_surround<G, A>(
self,
range: RangeInclusive<F::T>,
surround: A
) -> Anim<impl Fun<T = F::T, V = F::V>>where
G: Fun<T = F::T, V = F::V>,
A: Into<Anim<G>>,
pub fn squeeze_and_surround<G, A>( self, range: RangeInclusive<F::T>, surround: A ) -> Anim<impl Fun<T = F::T, V = F::V>>where G: Fun<T = F::T, V = F::V>, A: Into<Anim<G>>,
Transform an animation in time, so that its time [0 .. 1]
is shifted
and scaled into the given range
.
In other words, this function can both delay and speed up or slow down a given animation.
For time outside of the given range
, the surround
animation is used
instead.
Example
Go from zero to 2π in half a second:
// From zero to 2π in one second
let angle = pareen::circle();
// From zero to 2π in time range [0.5 .. 1.0]
let anim = angle.squeeze_and_surround(0.5..=1.0, 42.0);
assert_approx_eq!(anim.eval(0.0f32), 42.0f32);
assert_approx_eq!(anim.eval(0.5), 0.0);
assert_approx_eq!(anim.eval(1.0), std::f32::consts::PI * 2.0);
assert_approx_eq!(anim.eval(1.1), 42.0);
sourcepub fn seq_squeeze<G, A>(
self,
self_end: F::T,
next: A
) -> Anim<impl Fun<T = F::T, V = F::V>>where
G: Fun<T = F::T, V = F::V>,
A: Into<Anim<G>>,
pub fn seq_squeeze<G, A>( self, self_end: F::T, next: A ) -> Anim<impl Fun<T = F::T, V = F::V>>where G: Fun<T = F::T, V = F::V>, A: Into<Anim<G>>,
Play two animations in sequence, first playing self
until time
self_end
(non-inclusive), and then switching to next
. The animations
are squeezed in time so that they fit into [0 .. 1]
together.
self
is played in time [0 .. self_end)
, and then next
is played
in time [self_end .. 1]`.
source§impl<W, F> Anim<F>where
F: Fun,
F::T: Copy + Mul<W, Output = W>,
F::V: Copy + Add<W, Output = F::V> + Sub<Output = W>,
impl<W, F> Anim<F>where F: Fun, F::T: Copy + Mul<W, Output = W>, F::V: Copy + Add<W, Output = F::V> + Sub<Output = W>,
sourcepub fn lerp<G, A>(self, other: A) -> Anim<impl Fun<T = F::T, V = F::V>>where
G: Fun<T = F::T, V = F::V>,
A: Into<Anim<G>>,
pub fn lerp<G, A>(self, other: A) -> Anim<impl Fun<T = F::T, V = F::V>>where G: Fun<T = F::T, V = F::V>, A: Into<Anim<G>>,
Linearly interpolate between two animations, starting at time zero and finishing at time one.
Examples
Linearly interpolate between two constant values:
let anim = pareen::constant(5.0f32).lerp(10.0);
assert_approx_eq!(anim.eval(0.0f32), 5.0);
assert_approx_eq!(anim.eval(0.5), 7.5);
assert_approx_eq!(anim.eval(1.0), 10.0);
assert_approx_eq!(anim.eval(2.0), 15.0);
It is also possible to linearly interpolate between two non-constant animations:
let anim = pareen::circle().sin().lerp(pareen::circle().cos());
let value: f32 = anim.eval(0.5f32);
source§impl<V, F> Anim<F>where
F: Fun<V = Option<V>>,
F::T: Clone,
impl<V, F> Anim<F>where F: Fun<V = Option<V>>, F::T: Clone,
sourcepub fn unwrap_or<G, A>(self, default: A) -> Anim<impl Fun<T = F::T, V = V>>where
G: Fun<T = F::T, V = V>,
A: Into<Anim<G>>,
pub fn unwrap_or<G, A>(self, default: A) -> Anim<impl Fun<T = F::T, V = V>>where G: Fun<T = F::T, V = V>, A: Into<Anim<G>>,
Unwrap an animation of optional values.
At any time, returns the animation value if it is not None
, or the
given default
value otherwise.
Examples
let anim1 = pareen::constant(Some(42)).unwrap_or(-1);
assert_eq!(anim1.eval(2), 42);
assert_eq!(anim1.eval(3), 42);
let cond = pareen::fun(|t| t % 2 == 0);
let anim1 = pareen::cond(cond, Some(42), None).unwrap_or(-1);
assert_eq!(anim1.eval(2), 42);
assert_eq!(anim1.eval(3), -1);
sourcepub fn map_or<W, G, H, A>(
self,
default: A,
f: impl Fn(V) -> Anim<H>
) -> Anim<impl Fun<T = F::T, V = W>>where
G: Fun<T = F::T, V = W>,
H: Fun<T = F::T, V = W>,
A: Into<Anim<G>>,
pub fn map_or<W, G, H, A>( self, default: A, f: impl Fn(V) -> Anim<H> ) -> Anim<impl Fun<T = F::T, V = W>>where G: Fun<T = F::T, V = W>, H: Fun<T = F::T, V = W>, A: Into<Anim<G>>,
Applies a function to the contained value (if any), or returns the provided default (if not).
Note that the function f
itself returns an animation.
Example
Animate a player’s position offset if it is moving:
fn my_offset_anim(
move_dir: Option<f32>,
) -> pareen::Anim<impl pareen::Fun<T = f32, V = f32>> {
let move_speed = 2.0f32;
pareen::constant(move_dir).map_or(
0.0,
move |move_dir| pareen::prop(move_dir) * move_speed,
)
}
let move_anim = my_offset_anim(Some(1.0));
let stay_anim = my_offset_anim(None);
assert_approx_eq!(move_anim.eval(0.5), 1.0);
assert_approx_eq!(stay_anim.eval(0.5), 0.0);
source§impl<F> Anim<F>where
F: Fun + 'static,
F::T: Copy + PartialOrd + Sub<Output = F::T> + 'static,
F::V: 'static,
impl<F> Anim<F>where F: Fun + 'static, F::T: Copy + PartialOrd + Sub<Output = F::T> + 'static, F::V: 'static,
source§impl<F> Anim<F>where
F: Fun,
impl<F> Anim<F>where F: Fun,
sourcepub fn dur(self, t: F::T) -> AnimWithDur<F>
pub fn dur(self, t: F::T) -> AnimWithDur<F>
Tag this animation with the duration that it is intended to be played for.
Note that using this tagging is completely optional, but it may make it easier to combine animations sometimes.
source§impl<F> Anim<F>where
F: Fun,
F::T: Clone + FloatCore,
impl<F> Anim<F>where F: Fun, F::T: Clone + FloatCore,
pub fn scale_to_dur( self, dur: F::T ) -> AnimWithDur<impl Fun<T = F::T, V = F::V>>
source§impl<V, F> Anim<F>where
V: Float,
F: Fun<T = V, V = V>,
impl<V, F> Anim<F>where V: Float, F: Fun<T = V, V = V>,
sourcepub fn seq_ease_in<E, G, A>(
self,
self_end: V,
_easing: E,
ease_duration: V,
next: A
) -> Anim<impl Fun<T = V, V = V>>where
E: Easing<V>,
G: Fun<T = V, V = V>,
A: Into<Anim<G>>,
pub fn seq_ease_in<E, G, A>( self, self_end: V, _easing: E, ease_duration: V, next: A ) -> Anim<impl Fun<T = V, V = V>>where E: Easing<V>, G: Fun<T = V, V = V>, A: Into<Anim<G>>,
Play two animations in sequence, transitioning between them with an
easing-in function from
easer
.
This is only available when enabling the easer
feature for pareen
.
The values of self
at self_end
and of next
at time zero are used
to determine the parameters of the easing function.
Note that, as with seq
, the next
animation will see time starting at zero once it plays.
Arguments
self_end
- Time at which theself
animation is to stop._easing
- A struct implementingeaser::functions::Easing
. This determines the easing function that will be used for the transition. It is passed as a parameter here to simplify type inference.ease_duration
- The amount of time to use for transitioning tonext
.next
- The animation to play after transitioning.
Example
See seq_ease_in_out
for an example.
sourcepub fn seq_ease_out<E, G, A>(
self,
self_end: V,
_: E,
ease_duration: V,
next: A
) -> Anim<impl Fun<T = V, V = V>>where
E: Easing<V>,
G: Fun<T = V, V = V>,
A: Into<Anim<G>>,
pub fn seq_ease_out<E, G, A>( self, self_end: V, _: E, ease_duration: V, next: A ) -> Anim<impl Fun<T = V, V = V>>where E: Easing<V>, G: Fun<T = V, V = V>, A: Into<Anim<G>>,
Play two animations in sequence, transitioning between them with an
easing-out function from
easer
.
This is only available when enabling the easer
feature for pareen
.
The values of self
at self_end
and of next
at time zero are used
to determine the parameters of the easing function.
Note that, as with seq
, the next
animation will see time starting at zero once it plays.
Arguments
self_end
- Time at which theself
animation is to stop._easing
- A struct implementingeaser::functions::Easing
. This determines the easing function that will be used for the transition. It is passed as a parameter here to simplify type inference.ease_duration
- The amount of time to use for transitioning tonext
.next
- The animation to play after transitioning.
Example
See seq_ease_in_out
for an example.
sourcepub fn seq_ease_in_out<E, G, A>(
self,
self_end: V,
_: E,
ease_duration: V,
next: A
) -> Anim<impl Fun<T = V, V = V>>where
E: Easing<V>,
G: Fun<T = V, V = V>,
A: Into<Anim<G>>,
pub fn seq_ease_in_out<E, G, A>( self, self_end: V, _: E, ease_duration: V, next: A ) -> Anim<impl Fun<T = V, V = V>>where E: Easing<V>, G: Fun<T = V, V = V>, A: Into<Anim<G>>,
Play two animations in sequence, transitioning between them with an
easing-in-out function from
easer
.
This is only available when enabling the easer
feature for pareen
.
The values of self
at self_end
and of next
at time zero are used
to determine the parameters of the easing function.
Note that, as with seq
, the next
animation will see time starting at zero once it plays.
Arguments
self_end
- Time at which theself
animation is to stop._easing
- A struct implementingeaser::functions::Easing
. This determines the easing function that will be used for the transition. It is passed as a parameter here to simplify type inference.ease_duration
- The amount of time to use for transitioning tonext
.next
- The animation to play after transitioning.
Example
Play a constant value until time 0.5
, then transition for 0.3
time units, using a cubic function, into a second animation:
let first_anim = pareen::constant(2.0);
let second_anim = pareen::prop(1.0f32);
let anim = first_anim.seq_ease_in_out(
0.5,
easer::functions::Cubic,
0.3,
second_anim,
);
The animation will look like this: