Skip to main content

aura_anim_iced/timing/
mode.rs

1use crate::timing::utils::clamp_progress;
2
3/// Playback direction applied to repeated iterations.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
5pub enum Direction {
6    /// Play each iteration from start to end.
7    #[default]
8    Normal,
9    /// Play each iteration from end to start.
10    Reverse,
11    /// Alternate forward and reverse iterations.
12    Alternate,
13    /// Alternate reverse and forward iterations.
14    AlternateReverse,
15}
16
17impl Direction {
18    pub(crate) fn sample_progress(self, iteration_index: u32, raw_progress: f64) -> f64 {
19        let progress = clamp_progress(raw_progress);
20
21        if self.is_reversed_iteration(iteration_index) {
22            1.0 - progress
23        } else {
24            progress
25        }
26    }
27
28    pub(crate) fn start_progress(self) -> f64 {
29        self.sample_progress(0, 0.0)
30    }
31
32    pub(crate) fn end_progress(self, iteration_count: u32) -> f64 {
33        let last_iteration = iteration_count.saturating_sub(1);
34
35        self.sample_progress(last_iteration, 1.0)
36    }
37
38    fn is_reversed_iteration(self, iteration_index: u32) -> bool {
39        match self {
40            Self::Normal => false,
41            Self::Reverse => true,
42            Self::Alternate => iteration_index % 2 == 1,
43            Self::AlternateReverse => iteration_index.is_multiple_of(2),
44        }
45    }
46}
47
48/// How samples outside the active interval should be filled.
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
50pub enum FillMode {
51    /// Do not fill before or after the active interval.
52    #[default]
53    None,
54    /// Fill with the first active sample before the delay completes.
55    Backwards,
56    /// Fill with the final active sample after completion.
57    Forwards,
58    /// Fill both before the delay and after completion.
59    Both,
60}
61
62impl FillMode {
63    pub(crate) const fn fills_before_start(self) -> bool {
64        matches!(self, Self::Backwards | Self::Both)
65    }
66
67    pub(crate) const fn fills_after_end(self) -> bool {
68        matches!(self, Self::Forwards | Self::Both)
69    }
70}