use crate::curve::Curve;
use crate::easing::Easing;
use crate::spring::Spring;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Pair {
pub enter: Spring,
pub exit: Spring,
}
impl Pair {
pub const fn new(enter: Spring, exit: Spring) -> Pair {
Pair { enter, exit }
}
pub const fn pick(self, entering: bool) -> Spring {
if entering { self.enter } else { self.exit }
}
}
pub const INSTANT: Pair = Pair::new(Spring::new(0.10, 0.0), Spring::new(0.08, 0.0));
pub const SNAP: Pair = Pair::new(Spring::new(0.25, 0.0), Spring::new(0.20, 0.0));
pub const SETTLE: Pair = Pair::new(Spring::new(0.30, 0.0), Spring::new(0.24, 0.0));
pub const REFLOW: Pair = Pair::new(Spring::new(0.40, 0.0), Spring::new(0.32, 0.0));
pub const GLIDE: Pair = Pair::new(Spring::new(0.32, 0.0), Spring::new(0.26, 0.0));
pub const POP: Pair = Pair::new(Spring::new(0.25, 0.15), Spring::new(0.20, 0.0));
pub const DEFAULT: Pair = SETTLE;
pub const REDUCED_FADE: Curve = Curve::Tween { duration: 0.18, easing: Easing::EASE_IN_OUT };
pub const ALL: &[(&str, Pair)] = &[("instant", INSTANT), ("snap", SNAP), ("settle", SETTLE), ("reflow", REFLOW), ("glide", GLIDE), ("pop", POP)];
pub fn by_name(name: &str) -> Option<Pair> {
ALL.iter().find(|(n, _)| *n == name).map(|&(_, p)| p)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn exits_are_shorter() {
for (name, p) in ALL {
let ratio = p.exit.duration() / p.enter.duration();
assert!((0.75..=0.9 + 1e-6).contains(&ratio), "{name}: {ratio}");
assert!(p.exit.bounce() <= p.enter.bounce(), "{name}");
}
assert_eq!(by_name("settle"), Some(DEFAULT));
assert_eq!(by_name("nope"), None);
}
}