nuit_core/utils/
animation.rs

1use std::{fmt, time::Duration};
2
3use serde::{Deserialize, Serialize};
4
5/// An animation to use for smooth view transitions.
6#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase", rename_all_fields = "camelCase")]
8pub enum Animation {
9    Default {},
10    Curve { curve: AnimationCurve, duration_seconds: Option<f64> },
11    // TODO: Springs
12}
13
14/// The curve of a simple animation.
15#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
16#[serde(rename_all = "camelCase", rename_all_fields = "camelCase")]
17pub enum AnimationCurve {
18    Linear,
19    EaseIn,
20    EaseOut,
21    EaseInOut,
22}
23
24impl Animation {
25    pub const LINEAR: Self = Self::Curve { curve: AnimationCurve::Linear, duration_seconds: None };
26    pub const EASE_IN: Self = Self::Curve { curve: AnimationCurve::EaseIn, duration_seconds: None };
27    pub const EASE_OUT: Self = Self::Curve { curve: AnimationCurve::EaseOut, duration_seconds: None };
28    pub const EASE_IN_OUT: Self = Self::Curve { curve: AnimationCurve::EaseInOut, duration_seconds: None };
29
30    /// Creates an animation with the given curve and the given duration (or default if none).
31    pub fn curve(curve: AnimationCurve, duration: Option<Duration>) -> Self {
32        Self::Curve { curve, duration_seconds: duration.map(|d| d.as_secs_f64()) }
33    }
34
35    /// Creates an animation with a linear curve and the given duration (or default if none).
36    pub fn linear(duration: Duration) -> Self {
37        Self::curve(AnimationCurve::Linear, Some(duration))
38    }
39
40    /// Creates an animation with an ease-in curve and the given duration (or default if none).
41    pub fn ease_in(duration: Duration) -> Self {
42        Self::curve(AnimationCurve::EaseIn, Some(duration))
43    }
44
45    /// Creates an animation with an ease-out curve and the given duration (or default if none).
46    pub fn ease_out(duration: Duration) -> Self {
47        Self::curve(AnimationCurve::EaseOut, Some(duration))
48    }
49
50    /// Creates an animation with an ease-in/out curve and the given duration (or default if none).
51    pub fn ease_in_out(duration: Duration) -> Self {
52        Self::curve(AnimationCurve::EaseInOut, Some(duration))
53    }
54}
55
56impl Default for Animation {
57    fn default() -> Self {
58        Self::Default {}
59    }
60}
61
62impl fmt::Display for Animation {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        match self {
65            Self::Default {} => write!(f, "Default")?,
66            Self::Curve { curve, duration_seconds } => {
67                write!(f, "{}", curve)?;
68                if let Some(duration_seconds) = duration_seconds {
69                    write!(f, " ({}s)", duration_seconds)?;
70                }
71            },
72        }
73        Ok(())
74    }
75}
76
77impl fmt::Display for AnimationCurve {
78    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79        match self {
80            AnimationCurve::Linear => write!(f, "Linear"),
81            AnimationCurve::EaseIn => write!(f, "Ease in"),
82            AnimationCurve::EaseOut => write!(f, "Ease out"),
83            AnimationCurve::EaseInOut => write!(f, "Ease in/out"),
84        }
85    }
86}