1//! A collection of easing functions.
23use num_traits::{Float, FloatConst};
45/// Trait for things that can interpolate values.
6///
7/// See [this handy cheatsheet](https://easings.net).
8pub trait Interpolator<Value>: Float + FloatConst {
9/// Get a value self% between start and end.
10 /// `self` being 0 should mean all the way at `start`; `self` being 1 means all the way at `end`.
11 /// The implementation must accept values outside of 0 and 1, however,
12 /// for easing functions like `elastic_in`.
13 ///
14 /// All the easing functions are defined in terms of this function.
15 /// An equation is run on `self` to get a modified value, and the modified
16 /// value has `lerp` called on it.
17fn lerp(self, start: Value, end: Value) -> Value;
1819fn sine_in(self, start: Value, end: Value) -> Value {
20let it = Self::one() - ((self * Self::PI()) / Self::from(2).unwrap()).cos();
21 it.lerp(start, end)
22 }
23fn sine_out(self, start: Value, end: Value) -> Value {
24let it = ((self * Self::PI()) / Self::from(2).unwrap()).sin();
25 it.lerp(start, end)
26 }
27fn sine_in_out(self, start: Value, end: Value) -> Value {
28let it = -((self * Self::PI()).cos() - Self::one()) / Self::from(2).unwrap();
29 it.lerp(start, end)
30 }
3132fn quad_in(self, start: Value, end: Value) -> Value {
33let it = self * self;
34 it.lerp(start, end)
35 }
36fn quad_out(self, start: Value, end: Value) -> Value {
37let it = Self::one() - (Self::one() - self) * (Self::one() - self);
38 it.lerp(start, end)
39 }
40fn quad_in_out(self, start: Value, end: Value) -> Value {
41let two = Self::from(2).unwrap();
42let it = if self < Self::from(0.5).unwrap() {
43 two * self * self
44} else {
45Self::one() - (-two * self + two).powi(2) / two
46 };
47 it.lerp(start, end)
48 }
4950// impl the rest later
51}
5253impl<F> Interpolator<F> for F
54where
55F: Float + FloatConst,
56{
57fn lerp(self, start: F, end: F) -> F {
58 start * (Self::one() - self) + end * self
59}
60}
6162impl<F, const N: usize> Interpolator<[F; N]> for F
63where
64F: Float + FloatConst + Copy,
65{
66fn lerp(self, start: [F; N], end: [F; N]) -> [F; N] {
67let mut out = [Self::zero(); N];
68for i in 0..N {
69 out[i] = self.lerp(start[i], end[i]);
70 }
71 out
72 }
73}