smart_led_effects/strip/
wipe.rs

1use crate::strip::EffectIterator;
2use palette::{FromColor, Hsv, Srgb};
3use rand::Rng;
4
5pub struct Wipe {
6    position: usize,
7    buffer: Vec<Srgb<u8>>,
8    reverse: bool,
9    end: usize,
10    count: usize,
11    randomize: bool,
12}
13
14impl Wipe {
15    pub fn new(count: usize, data: Vec<Srgb<u8>>, reverse: bool) -> Self {
16        let mut buffer = vec![Srgb::<u8>::new(0, 0, 0); count];
17        buffer.extend(data);
18        buffer.extend(vec![Srgb::<u8>::new(0, 0, 0); count]);
19
20        let end = buffer.len() - count;
21
22        Wipe {
23            position: match reverse {
24                true => end,
25                false => 0,
26            },
27            buffer,
28            reverse,
29            end,
30            count,
31            randomize: false,
32        }
33    }
34
35    pub fn colour_wipe(count: usize, colour: Option<Srgb<u8>>, reverse: bool) -> Self {
36        let mut s = Wipe::new(count, vec![Srgb::new(0, 0, 0); count], reverse);
37        match colour {
38            Some(colour) => s.fill_wipe(colour),
39            None => s.randomize_colour_wipe(),
40        }
41        s
42    }
43
44    fn fill_wipe(&mut self, colour: Srgb<u8>) {
45        let mut buffer = vec![Srgb::<u8>::new(0, 0, 0); self.count];
46        buffer.extend(vec![colour; self.count]);
47        buffer.extend(vec![Srgb::<u8>::new(0, 0, 0); self.count]);
48        self.buffer = buffer;
49    }
50
51    fn randomize_colour_wipe(&mut self) {
52        let mut rng = rand::thread_rng();
53        let colour: Srgb<u8> =
54            Srgb::from_color(Hsv::new(rng.gen_range(0.0..360.0), 1.0, 1.0)).into_format();
55        self.fill_wipe(colour);
56        self.randomize = true;
57    }
58}
59
60impl EffectIterator for Wipe {
61    fn name(&self) -> &'static str {
62        "Wipe"
63    }
64
65    fn next(&mut self) -> Option<Vec<Srgb<u8>>> {
66        let out = self
67            .buffer
68            .iter()
69            .skip(self.position)
70            .take(self.count)
71            .copied()
72            .collect::<Vec<Srgb<u8>>>();
73
74        if self.reverse {
75            self.position -= 1;
76            if self.position == 0 {
77                self.position = self.end;
78                if self.randomize {
79                    self.randomize_colour_wipe();
80                }
81            }
82        } else {
83            self.position += 1;
84            if self.position >= self.end {
85                self.position = 0;
86                if self.randomize {
87                    self.randomize_colour_wipe();
88                }
89            }
90        }
91        Some(out)
92    }
93}