#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
pub enum AnimationToken {
DurationFastest,
DurationFaster,
DurationFast,
DurationNormal,
DurationSlow,
DurationSlower,
DurationSlowest,
}
#[derive(Clone, Copy, Debug, PartialEq, Default)]
pub enum Easing {
Linear,
EaseIn,
#[default]
EaseOut,
EaseInOut,
CubicBezier(f32, f32, f32, f32),
}
impl Easing {
pub fn evaluate(&self, t: f32) -> f32 {
let t = t.clamp(0.0, 1.0);
match self {
Easing::Linear => t,
Easing::EaseIn => t * t,
Easing::EaseOut => 1.0 - (1.0 - t) * (1.0 - t),
Easing::EaseInOut => {
if t < 0.5 {
2.0 * t * t
} else {
1.0 - (-2.0 * t + 2.0).powi(2) / 2.0
}
}
Easing::CubicBezier(x1, y1, x2, y2) => {
cubic_bezier_approximate(t, *x1, *y1, *x2, *y2)
}
}
}
}
fn cubic_bezier_approximate(t: f32, _x1: f32, y1: f32, _x2: f32, y2: f32) -> f32 {
let t2 = t * t;
let t3 = t2 * t;
let mt = 1.0 - t;
let mt2 = mt * mt;
3.0 * mt2 * t * y1 + 3.0 * mt * t2 * y2 + t3
}
#[derive(Clone, Debug)]
pub struct AnimationTokens {
pub duration_fastest: u64,
pub duration_faster: u64,
pub duration_fast: u64,
pub duration_normal: u64,
pub duration_slow: u64,
pub duration_slower: u64,
pub duration_slowest: u64,
pub ease_default: Easing,
pub ease_in: Easing,
pub ease_out: Easing,
pub ease_in_out: Easing,
}
impl AnimationTokens {
pub fn get(&self, token: AnimationToken) -> u64 {
match token {
AnimationToken::DurationFastest => self.duration_fastest,
AnimationToken::DurationFaster => self.duration_faster,
AnimationToken::DurationFast => self.duration_fast,
AnimationToken::DurationNormal => self.duration_normal,
AnimationToken::DurationSlow => self.duration_slow,
AnimationToken::DurationSlower => self.duration_slower,
AnimationToken::DurationSlowest => self.duration_slowest,
}
}
pub fn get_seconds(&self, token: AnimationToken) -> f32 {
self.get(token) as f32 / 1000.0
}
}
impl Default for AnimationTokens {
fn default() -> Self {
Self {
duration_fastest: 75,
duration_faster: 100,
duration_fast: 150,
duration_normal: 200,
duration_slow: 300,
duration_slower: 400,
duration_slowest: 500,
ease_default: Easing::EaseOut,
ease_in: Easing::EaseIn,
ease_out: Easing::EaseOut,
ease_in_out: Easing::EaseInOut,
}
}
}