~ruther/map-led-strip

ref: bd185825a32c333777843f20300148d5226d6573 map-led-strip/src/animations/snake_animation.rs -rw-r--r-- 2.2 KiB
bd185825 — František Boháček fix: set finished of snake animation on the last step, not after 1 year, 9 months ago
                                                                                
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
use core::cmp::max;
use esp_println::println;
use fugit::MicrosDurationU64;
use libm::{ceilf, powf};
use smart_leds::RGB8;
use crate::animations::animation::{Animation, AnimationError};
use crate::animations::animation_step::AnimationStep;
use crate::map::Map;

pub struct SnakeAnimation<const LEDS_COUNT: usize> {
    step: usize,
    finished: bool,
    order: [usize; LEDS_COUNT],
    previous_factor: f32,
    color: RGB8,
    step_duration: MicrosDurationU64,
}

impl<const LEDS_COUNT: usize> SnakeAnimation<LEDS_COUNT> {
    pub fn new(order: [usize; LEDS_COUNT], previous_factor: f32, color: RGB8, step_duration: MicrosDurationU64) -> Self {
        Self {
            step: 0,
            finished: false,
            order,
            previous_factor,
            color,
            step_duration
        }
    }

    fn is_first_step(&self) -> bool {
        self.step == 1
    }

    fn is_last_step(&self) -> bool {
        self.finished
    }
}

impl<const LEDS_COUNT: usize> Animation for SnakeAnimation<LEDS_COUNT> {
    fn is_started(&self) -> bool {
        self.step > 0
    }

    fn init(&mut self) -> Result<(), AnimationError> {
        Ok(())
    }

    fn next(&mut self) -> Result<AnimationStep, AnimationError> {
        let last = LEDS_COUNT + 100;
        if self.step == last {
            return Err(AnimationError::LastStep);
        }

        self.step += 1;
        if self.step == last {
            self.finished = true;
        }

        Ok(AnimationStep::new(self.step_duration))
    }

    fn apply(&mut self, map: &mut Map) -> Result<(), AnimationError> {
        if self.is_first_step() {
            map.clear();
        }

        for (i, led_index) in self.order.iter().take(self.step.max(LEDS_COUNT)).enumerate() {
            let mult_factor = self.step - i - 1;
            let coeff = powf(self.previous_factor, mult_factor as f32);
            let rgb = self.color;
            let color = RGB8 {
                r: ceilf(rgb.r as f32 * coeff) as u8,
                g: ceilf(rgb.g as f32 * coeff) as u8,
                b: ceilf(rgb.r as f32 * coeff) as u8,
            };

            map.set(*led_index, color).ok().unwrap();
        }

        if self.is_last_step() {
            map.clear();
        }

        Ok(())
    }
}
Do not follow this link