56 lines
1.6 KiB
Rust
56 lines
1.6 KiB
Rust
use crate::patterns::{Pattern, PixelColor};
|
|
use crate::{impl_pattern_init_background, impl_pattern_last_iteration, Strip};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
/// # RingScanner
|
|
///
|
|
/// display a ring on the strip fading for the previous ones
|
|
#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)]
|
|
pub struct RingScanner<const N: usize> {
|
|
#[serde(default)]
|
|
pub(crate) current_iteration: usize,
|
|
pub(crate) max_iteration: Option<usize>,
|
|
pub(crate) color: PixelColor,
|
|
pub(crate) background_color: Option<PixelColor>,
|
|
pub(crate) ring_size: usize,
|
|
}
|
|
|
|
impl<const N: usize> Pattern for RingScanner<N> {
|
|
type Strip = Strip<N>;
|
|
impl_pattern_init_background!(N);
|
|
impl_pattern_last_iteration!(ColorWipe);
|
|
}
|
|
|
|
impl<const N: usize> Iterator for RingScanner<N> {
|
|
type Item = Strip<N>;
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
if self.is_last_iteration() {
|
|
return None;
|
|
}
|
|
|
|
let mut strip: Strip<N>;
|
|
|
|
if let Some(color) = self.background_color {
|
|
strip = Strip::new(color);
|
|
} else {
|
|
strip = Strip::default();
|
|
}
|
|
|
|
let nbr_iter = N / self.ring_size;
|
|
let iter = self.current_iteration % nbr_iter;
|
|
|
|
for j in 0..iter {
|
|
let first_index = j * self.ring_size;
|
|
let last_index = first_index + self.ring_size;
|
|
let fade_gain = 2 * (iter - j);
|
|
for i in first_index..last_index {
|
|
strip[i] = Some(self.color / fade_gain as u8);
|
|
}
|
|
}
|
|
|
|
self.current_iteration += 1;
|
|
Some(strip)
|
|
}
|
|
}
|