smart_led_effects/strip/
snow_sparkle.rs1use crate::strip::EffectIterator;
2use palette::{Hsv, Srgb};
3use rand::{thread_rng, Rng};
4
5use crate::utils::{hsv_to_srgb, srgbu8_to_hsv};
6
7pub struct SnowSparkle {
8 frequency: u8,
9 probability: f32,
10 fade: f32,
11 colour: Hsv,
12 current: Vec<Hsv>,
13}
14
15impl SnowSparkle {
16 const DEFAULT_FREQUENCY: u8 = 0x04;
17 const DEFAULT_PROBABILITY: f32 = 0.1;
18 const DEFAULT_FADE: f32 = 0.4;
19 const BASE_BRIGHTNESS: f32 = 0.2;
20 pub fn new(
21 count: usize,
22 colour: Option<Srgb<u8>>,
23 sparkle: Option<u8>,
24 probability: Option<f32>,
25 fade: Option<f32>,
26 ) -> Self {
27 let mut colour = match colour {
28 Some(colour) => srgbu8_to_hsv(colour),
29 None => Hsv::new(0.0, 0.0, 1.0),
30 };
31
32 colour.value = SnowSparkle::BASE_BRIGHTNESS;
33
34 SnowSparkle {
35 frequency: sparkle.unwrap_or(SnowSparkle::DEFAULT_FREQUENCY),
36 fade: fade.unwrap_or(SnowSparkle::DEFAULT_FADE),
37 probability: probability.unwrap_or(SnowSparkle::DEFAULT_PROBABILITY),
38 current: vec![colour; count],
39 colour,
40 }
41 }
42
43 pub fn sparkle(count: usize, colour: Option<Srgb<u8>>) -> Self {
44 let colour = match colour {
45 Some(colour) => Some(colour),
46 None => Some(Srgb::<u8>::new(255, 255, 255)),
47 };
48 SnowSparkle::new(count, colour, Some(20), Some(0.4), Some(1.0))
49 }
50}
51
52impl SnowSparkle {
53 fn generate_sparkle(&mut self) {
54 let mut rng = thread_rng();
55 let index = rng.gen_range(0..self.current.len());
56
57 let mut sparkle = self.colour;
58 sparkle.value = rng.gen_range(0.5..1.0);
59
60 let chance = rng.gen_range(0.0..1.0);
61 if chance < self.probability {
62 self.current[index] = sparkle;
63 }
64 }
65
66 fn fade_sparkles(&mut self) {
67 for pixel in self.current.iter_mut() {
68 pixel.value = (pixel.value - self.fade).max(Self::BASE_BRIGHTNESS);
69 }
70 }
71}
72
73impl EffectIterator for SnowSparkle {
74 fn name(&self) -> &'static str {
75 "SnowSparkle"
76 }
77
78 fn next(&mut self) -> Option<Vec<Srgb<u8>>> {
79 self.fade_sparkles();
80
81 let chances = thread_rng().gen_range(0..self.frequency);
82 for _ in 0..chances {
83 self.generate_sparkle();
84 }
85
86 Some(hsv_to_srgb(self.current.clone()))
87 }
88}