smart_led_effects 0.1.8

A collection of effects for LED strips
Documentation
use crate::strip::EffectIterator;
use palette::{Darken, Srgb};
use rand::{thread_rng, Rng};
pub struct Meteor {
    count: usize,
    colour: Srgb,
    size: usize,
    position: usize,
    fade: f32,
    current: Vec<Srgb>,
    random_colour: bool,
}

impl Meteor {
    const DEFAULT_SIZE: usize = 4;
    const DEFAULT_FADE: f32 = 0.3;
    const DEFAULT_COLOUR: Srgb<u8> = Srgb::<u8>::new(255, 255, 255);

    pub fn new(
        count: usize,
        colour: Option<Srgb<u8>>,
        size: Option<usize>,
        fade: Option<f32>,
    ) -> Self {
        Meteor {
            count,
            colour: colour.unwrap_or(Self::DEFAULT_COLOUR).into_format(),
            size: size.unwrap_or(Self::DEFAULT_SIZE),
            position: 0,
            fade: fade.unwrap_or(Self::DEFAULT_FADE),
            current: vec![Srgb::new(0.0, 0.0, 0.0); count],
            random_colour: colour.is_none(),
        }
    }
}

impl EffectIterator for Meteor {
    fn name(&self) -> &'static str {
        "Meteor"
    }

    fn next(&mut self) -> Option<Vec<Srgb<u8>>> {
        let mut rng = thread_rng();
        for pixel in self.current.iter_mut() {
            if rng.gen_range(0.0..1.0) < 0.5 {
                *pixel = pixel.darken(self.fade);
            }
        }

        for i in 0..self.size {
            if (self.position.saturating_sub(i) < self.count) && (self.position >= i) {
                self.current[self.position - i] = self.colour;
            }
        }
        self.position += 1;
        if self.position > 2 * self.count {
            if self.random_colour {
                self.colour = Srgb::new(
                    rng.gen_range(0.0..1.0),
                    rng.gen_range(0.0..1.0),
                    rng.gen_range(0.0..1.0),
                );
            }
            self.position = 0;
        }

        Some(self.current.iter().map(|p| p.into_format()).collect())
    }
}