use std::fmt; #[derive(Clone, Copy, Debug, Default)] pub struct PixelColor { pub(crate) red: u8, pub(crate) green: u8, pub(crate) blue: u8, } impl PixelColor { fn new() -> Self { Default::default() } } impl fmt::Display for PixelColor { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "[{},{},{}]", self.red, self.green, self.blue) } } #[derive(Copy, Clone)] pub struct Strip { pub strip: [PixelColor; N], } impl Strip { pub fn to_array(self) -> Vec { let mut data: Vec = vec![]; for i in 0..N { data.append(&mut vec![ self.strip[i].green, self.strip[i].red, self.strip[i].blue, ]); } data } pub fn fill(&mut self, color: PixelColor) { self.strip = [color; N]; } } impl Default for Strip { fn default() -> Self { Strip { strip: [PixelColor::new(); N], } } } /// Rainbow pattern ///////////////////////////////////////////////// pub struct Rainbow { pub(crate) current_iteration: usize, pub(crate) max_iteration: Option, pub(crate) step: Option, } impl Iterator for Rainbow { type Item = Strip; fn next(&mut self) -> Option { if let Some(nbr_iteration) = self.max_iteration { if nbr_iteration == self.current_iteration { return None; } } let mut strip = Strip::default(); let step = self.step.unwrap_or(255 / N); for i in 0..N { let pos = (i * step + self.current_iteration) as u8; strip.strip[i] = wheel(pos) } self.current_iteration += 1; Some(strip) } } fn wheel(index: u8) -> PixelColor { let pos = 255 - index; match pos { 0..=85 => PixelColor { red: 255 - (pos * 3), green: 0, blue: pos * 3, }, 86..=170 => { let pos = pos - 85; PixelColor { red: 0, green: pos * 3, blue: 255 - (pos * 3), } } _ => { let pos = pos - 170; PixelColor { red: pos * 3, green: 255 - (pos * 3), blue: 0, } } } } ////////////////////////////////////////////////////////////////////////// /// Colorwipe pattern //////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// pub struct ColorWipe { pub(crate) current_iteration: usize, pub(crate) color: PixelColor, pub(crate) infinite: bool, } impl Iterator for ColorWipe { type Item = Strip; fn next(&mut self) -> Option { let mut strip = Strip::default(); if self.infinite { self.current_iteration %= N; } else if self.current_iteration >= N { return None; } for i in 0..self.current_iteration { strip.strip[i] = self.color; } self.current_iteration += 1; Some(strip) } } ////////////////////////////////////////////////////////////////////////// /// fade pattern //////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// pub struct Fade { pub(crate) current_iteration: usize, pub(crate) nbr_iterations: usize, pub(crate) begin_color: PixelColor, pub(crate) end_color: PixelColor, } fn fade_value(value_start: u8, value_end: u8, index: usize, nbr_iter: usize) -> u8 { ((value_start as usize * (nbr_iter - index) + value_end as usize * index) / nbr_iter) as u8 } impl Iterator for Fade { type Item = Strip; fn next(&mut self) -> Option { let mut strip = Strip::default(); if self.current_iteration >= self.nbr_iterations { return None; } let red = fade_value( self.begin_color.red, self.end_color.red, self.current_iteration, self.nbr_iterations, ); let green = fade_value( self.begin_color.green, self.end_color.green, self.current_iteration, self.nbr_iterations, ); let blue = fade_value( self.begin_color.blue, self.end_color.blue, self.current_iteration, self.nbr_iterations, ); let current_color = PixelColor { red, green, blue }; strip.fill(current_color); self.current_iteration += 1; Some(strip) } }