Skip to main content

telar_motion_core/
curve.rs

1use std::time::Duration;
2
3use crate::easing::Easing;
4
5/// A time-based interpolation over a fixed `duration` shaped by `easing`.
6#[derive(Debug, Clone, Copy, PartialEq)]
7pub struct Tween {
8    pub duration: Duration,
9    pub easing: Easing,
10}
11
12/// A physical spring parameterized by raw `stiffness`, `damping`, and `mass`.
13#[derive(Debug, Clone, Copy, PartialEq)]
14pub struct Spring {
15    pub stiffness: f32,
16    pub damping: f32,
17    pub mass: f32,
18}
19
20/// The motion model backing an [`crate::Animated`] value.
21#[derive(Debug, Clone, Copy, PartialEq)]
22pub enum Curve {
23    Tween(Tween),
24    Spring(Spring),
25}
26
27/// Build a [`Tween`] from a duration and easing.
28pub fn tween(duration: Duration, easing: Easing) -> Tween {
29    Tween { duration, easing }
30}
31
32/// Build a [`Spring`] from stiffness and damping; mass defaults to 1.0.
33pub fn spring(stiffness: f32, damping: f32) -> Spring {
34    Spring {
35        stiffness,
36        damping,
37        mass: 1.0,
38    }
39}
40
41impl Spring {
42    /// Soft settle with essentially no overshoot; scale mirrors the near-critical spring(170, 26) used for the sandbox theme-color transition.
43    pub fn gentle() -> Spring {
44        spring(120.0, 14.0)
45    }
46
47    /// Fast, firm settle for interactive feedback (button presses, toggles).
48    pub fn snappy() -> Spring {
49        spring(210.0, 20.0)
50    }
51
52    /// Visible overshoot before settling; scale mirrors the underdamped spring(170, 12) used for the sandbox scale demo.
53    pub fn bouncy() -> Spring {
54        spring(180.0, 12.0)
55    }
56}
57
58impl From<Tween> for Curve {
59    fn from(t: Tween) -> Self {
60        Curve::Tween(t)
61    }
62}
63
64impl From<Spring> for Curve {
65    fn from(s: Spring) -> Self {
66        Curve::Spring(s)
67    }
68}