use easer::functions::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Ease {
#[default]
Linear,
QuadIn,
QuadOut,
QuadInOut,
CubicIn,
CubicOut,
CubicInOut,
QuartIn,
QuartOut,
QuartInOut,
QuintIn,
QuintOut,
QuintInOut,
SineIn,
SineOut,
SineInOut,
CircIn,
CircOut,
CircInOut,
ExpoIn,
ExpoOut,
ExpoInOut,
ElasticIn,
ElasticOut,
ElasticInOut,
BackIn,
BackOut,
BackInOut,
BounceIn,
BounceOut,
BounceInOut,
}
impl Ease {
#[inline]
pub fn sample(&self, ratio: f32) -> f32 {
const B: f32 = 0.0;
const C: f32 = 1.0;
const D: f32 = 1.0;
match self {
Ease::Linear => Linear::ease_in(ratio, B, C, D),
Ease::QuadIn => Quad::ease_in(ratio, B, C, D),
Ease::QuadOut => Quad::ease_out(ratio, B, C, D),
Ease::QuadInOut => Quad::ease_in_out(ratio, B, C, D),
Ease::CubicIn => Cubic::ease_in(ratio, B, C, D),
Ease::CubicOut => Cubic::ease_out(ratio, B, C, D),
Ease::CubicInOut => Cubic::ease_in_out(ratio, B, C, D),
Ease::QuartIn => Quart::ease_in(ratio, B, C, D),
Ease::QuartOut => Quart::ease_out(ratio, B, C, D),
Ease::QuartInOut => Quart::ease_in_out(ratio, B, C, D),
Ease::QuintIn => Quint::ease_in(ratio, B, C, D),
Ease::QuintOut => Quint::ease_out(ratio, B, C, D),
Ease::QuintInOut => Quint::ease_in_out(ratio, B, C, D),
Ease::SineIn => Sine::ease_in(ratio, B, C, D),
Ease::SineOut => Sine::ease_out(ratio, B, C, D),
Ease::SineInOut => Sine::ease_in_out(ratio, B, C, D),
Ease::CircIn => Circ::ease_in(ratio, B, C, D),
Ease::CircOut => Circ::ease_out(ratio, B, C, D),
Ease::CircInOut => Circ::ease_in_out(ratio, B, C, D),
Ease::ExpoIn => Expo::ease_in(ratio, B, C, D),
Ease::ExpoOut => Expo::ease_out(ratio, B, C, D),
Ease::ExpoInOut => Expo::ease_in_out(ratio, B, C, D),
Ease::ElasticIn => Elastic::ease_in(ratio, B, C, D),
Ease::ElasticOut => Elastic::ease_out(ratio, B, C, D),
Ease::ElasticInOut => Elastic::ease_in_out(ratio, B, C, D),
Ease::BackIn => Back::ease_in(ratio, B, C, D),
Ease::BackOut => Back::ease_out(ratio, B, C, D),
Ease::BackInOut => Back::ease_in_out(ratio, B, C, D),
Ease::BounceIn => Bounce::ease_in(ratio, B, C, D),
Ease::BounceOut => Bounce::ease_out(ratio, B, C, D),
Ease::BounceInOut => Bounce::ease_in_out(ratio, B, C, D),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
const ALL_EASES: [Ease; 31] = [
Ease::Linear,
Ease::QuadIn,
Ease::QuadOut,
Ease::QuadInOut,
Ease::CubicIn,
Ease::CubicOut,
Ease::CubicInOut,
Ease::QuartIn,
Ease::QuartOut,
Ease::QuartInOut,
Ease::QuintIn,
Ease::QuintOut,
Ease::QuintInOut,
Ease::SineIn,
Ease::SineOut,
Ease::SineInOut,
Ease::CircIn,
Ease::CircOut,
Ease::CircInOut,
Ease::ExpoIn,
Ease::ExpoOut,
Ease::ExpoInOut,
Ease::ElasticIn,
Ease::ElasticOut,
Ease::ElasticInOut,
Ease::BackIn,
Ease::BackOut,
Ease::BackInOut,
Ease::BounceIn,
Ease::BounceOut,
Ease::BounceInOut,
];
#[test]
fn test_endpoints() {
for ease in ALL_EASES {
let start = ease.sample(0.0);
let end = ease.sample(1.0);
assert!(
start.abs() < 1e-4,
"Ease::{:?} failed start endpoint: got {}",
ease,
start
);
assert!(
(end - 1.0).abs() < 1e-4,
"Ease::{:?} failed end endpoint: got {}",
ease,
end
);
}
}
#[test]
fn test_midpoints() {
let mid = Ease::QuadInOut.sample(0.5);
assert!((mid - 0.5).abs() < 1e-4);
let mid_linear = Ease::Linear.sample(0.5);
assert!((mid_linear - 0.5).abs() < 1e-4);
let mid_quad_in = Ease::QuadIn.sample(0.5);
assert!((mid_quad_in - 0.25).abs() < 1e-4);
}
}