57 lines
1.5 KiB
Rust
57 lines
1.5 KiB
Rust
use crate::patterns::{Pattern, PixelColor};
|
|
use crate::Strip;
|
|
use serde::{Serialize, Deserialize};
|
|
|
|
/// # scanner pattern
|
|
/// color one pixel with a color and leave a train of this color fading to black
|
|
///
|
|
/// # note
|
|
///
|
|
/// background_color work only for color not set by scanner pattern
|
|
#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)]
|
|
pub struct Scanner<const N: usize> {
|
|
#[serde(default)]
|
|
pub(crate) current_iteration: usize,
|
|
pub(crate) color: PixelColor,
|
|
pub(crate) background_color: Option<PixelColor>,
|
|
}
|
|
|
|
impl<const N:usize> Pattern for Scanner<N> {
|
|
type Strip = Strip<N>;
|
|
|
|
fn init(&self) -> Option<Self::Strip> {
|
|
if let Some(color) = self.background_color {
|
|
Some(Strip::<N>::new(color))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<const N: usize> Iterator for Scanner<N> {
|
|
type Item = Strip<N>;
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
let mut strip = Strip::<N>::default();
|
|
if let Some(c) = self.background_color {
|
|
strip.fill(c);
|
|
} else {
|
|
strip.fill(PixelColor::default());
|
|
}
|
|
|
|
let current_led = self.current_iteration % N;
|
|
let min_led;
|
|
if current_led < 8 {
|
|
min_led = 0;
|
|
} else {
|
|
min_led = current_led - 8;
|
|
}
|
|
let mut c = self.color;
|
|
for i in min_led..current_led {
|
|
strip[i] = Some(c);
|
|
c = c / 2;
|
|
}
|
|
self.current_iteration += 1;
|
|
Some(strip)
|
|
}
|
|
} |