iced_core/
animation.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! Animate your applications.
use crate::time::{Duration, Instant};

pub use lilt::{Easing, FloatRepresentable as Float, Interpolable};

/// The animation of some particular state.
///
/// It tracks state changes and allows projecting interpolated values
/// through time.
#[derive(Debug, Clone)]
pub struct Animation<T>
where
    T: Clone + Copy + PartialEq + Float,
{
    raw: lilt::Animated<T, Instant>,
}

impl<T> Animation<T>
where
    T: Clone + Copy + PartialEq + Float,
{
    /// Creates a new [`Animation`] with the given initial state.
    pub fn new(state: T) -> Self {
        Self {
            raw: lilt::Animated::new(state),
        }
    }

    /// Sets the [`Easing`] function of the [`Animation`].
    ///
    /// See the [Easing Functions Cheat Sheet](https://easings.net) for
    /// details!
    pub fn easing(mut self, easing: Easing) -> Self {
        self.raw = self.raw.easing(easing);
        self
    }

    /// Sets the duration of the [`Animation`] to 100ms.
    pub fn very_quick(self) -> Self {
        self.duration(Duration::from_millis(100))
    }

    /// Sets the duration of the [`Animation`] to 200ms.
    pub fn quick(self) -> Self {
        self.duration(Duration::from_millis(200))
    }

    /// Sets the duration of the [`Animation`] to 400ms.
    pub fn slow(self) -> Self {
        self.duration(Duration::from_millis(400))
    }

    /// Sets the duration of the [`Animation`] to 500ms.
    pub fn very_slow(self) -> Self {
        self.duration(Duration::from_millis(500))
    }

    /// Sets the duration of the [`Animation`] to the given value.
    pub fn duration(mut self, duration: Duration) -> Self {
        self.raw = self.raw.duration(duration.as_secs_f32() * 1_000.0);
        self
    }

    /// Sets a delay for the [`Animation`].
    pub fn delay(mut self, duration: Duration) -> Self {
        self.raw = self.raw.delay(duration.as_secs_f64() as f32 * 1000.0);
        self
    }

    /// Makes the [`Animation`] repeat a given amount of times.
    ///
    /// Providing 1 repetition plays the animation twice in total.
    pub fn repeat(mut self, repetitions: u32) -> Self {
        self.raw = self.raw.repeat(repetitions);
        self
    }

    /// Makes the [`Animation`] repeat forever.
    pub fn repeat_forever(mut self) -> Self {
        self.raw = self.raw.repeat_forever();
        self
    }

    /// Makes the [`Animation`] automatically reverse when repeating.
    pub fn auto_reverse(mut self) -> Self {
        self.raw = self.raw.auto_reverse();
        self
    }

    /// Transitions the [`Animation`] from its current state to the given new state.
    pub fn go(mut self, new_state: T) -> Self {
        self.go_mut(new_state);
        self
    }

    /// Transitions the [`Animation`] from its current state to the given new state, by reference.
    pub fn go_mut(&mut self, new_state: T) {
        self.raw.transition(new_state, Instant::now());
    }

    /// Returns true if the [`Animation`] is currently in progress.
    ///
    /// An [`Animation`] is in progress when it is transitioning to a different state.
    pub fn is_animating(&self, at: Instant) -> bool {
        self.raw.in_progress(at)
    }

    /// Projects the [`Animation`] into an interpolated value at the given [`Instant`]; using the
    /// closure provided to calculate the different keyframes of interpolated values.
    ///
    /// If the [`Animation`] state is a `bool`, you can use the simpler [`interpolate`] method.
    ///
    /// [`interpolate`]: Animation::interpolate
    pub fn interpolate_with<I>(&self, f: impl Fn(T) -> I, at: Instant) -> I
    where
        I: Interpolable,
    {
        self.raw.animate(f, at)
    }

    /// Retuns the current state of the [`Animation`].
    pub fn value(&self) -> T {
        self.raw.value
    }
}

impl Animation<bool> {
    /// Projects the [`Animation`] into an interpolated value at the given [`Instant`]; using the
    /// `start` and `end` values as the origin and destination keyframes.
    pub fn interpolate<I>(&self, start: I, end: I, at: Instant) -> I
    where
        I: Interpolable + Clone,
    {
        self.raw.animate_bool(start, end, at)
    }
}