add ring and ringscanner pattern

This commit is contained in:
Tobias Ollive 2022-03-12 21:20:55 +01:00
parent 4dd5587b49
commit 20b8f6d4db
6 changed files with 155 additions and 13 deletions

View File

@ -55,15 +55,9 @@
- name: titi
sequence:
- pattern:
type: FadeRandom
fade :
steps: 50
begin_color: *black
end_color: &cyan
red: 0
green: 255
blue: 255
stability : 30
type: RingScanner
color: *green
ring_size: 4
max_iteration : 50
period: 100
- pattern:

View File

@ -7,6 +7,8 @@ mod fill_random;
mod fill_unstable;
mod rain;
mod rainbow;
mod ring;
mod ring_scanner;
mod scanner;
use crate::patterns::blink::Blink;
@ -18,6 +20,8 @@ use crate::patterns::fill_random::FillRandom;
use crate::patterns::fill_unstable::FillUnstable;
use crate::patterns::rain::Rain;
use crate::patterns::rainbow::Rainbow;
use crate::patterns::ring::Ring;
use crate::patterns::ring_scanner::RingScanner;
use crate::patterns::scanner::Scanner;
use rand::rngs::ThreadRng;
use rand::Rng;
@ -38,6 +42,8 @@ pub(crate) enum Patterns<const N: usize> {
Rain(Rain<N>),
FadeRandom(FadeRandom<N>),
FadeUnstable(FadeUnstable<N>),
Ring(Ring<N>),
RingScanner(RingScanner<N>),
}
pub trait Pattern: Iterator {
@ -62,6 +68,8 @@ impl<const N: usize> Iterator for Patterns<N> {
Patterns::Rain(p) => p.next(),
Patterns::FadeRandom(p) => p.next(),
Patterns::FadeUnstable(p) => p.next(),
Patterns::Ring(p) => p.next(),
Patterns::RingScanner(p) => p.next(),
}
}
}
@ -81,6 +89,8 @@ impl<const N: usize> Pattern for Patterns<N> {
Patterns::Rain(p) => p.init(),
Patterns::FadeRandom(p) => p.init(),
Patterns::FadeUnstable(p) => p.init(),
Patterns::Ring(p) => p.init(),
Patterns::RingScanner(p) => p.init(),
}
}
@ -96,6 +106,8 @@ impl<const N: usize> Pattern for Patterns<N> {
Patterns::Rain(p) => p.is_last_iteration(),
Patterns::FadeRandom(p) => p.is_last_iteration(),
Patterns::FadeUnstable(p) => p.is_last_iteration(),
Patterns::Ring(p) => p.is_last_iteration(),
Patterns::RingScanner(p) => p.is_last_iteration(),
}
}
}

View File

@ -3,9 +3,9 @@ use crate::patterns::Pattern;
use crate::Strip;
use serde::{Deserialize, Serialize};
/// # Blink
/// # FadeRandom
///
/// fade from one color to an other then go back several times
/// fade from one color to an other with random variations applied to each pixel
#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)]
pub struct FadeRandom<const N: usize> {
#[serde(default)]

View File

@ -3,9 +3,9 @@ use crate::patterns::Pattern;
use crate::Strip;
use serde::{Deserialize, Serialize};
/// # Blink
/// # FadeUnstable
///
/// fade from one color to an other then go back several times
/// fade from one color to an other with random variations applied to the entire strip
#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)]
pub struct FadeUnstable<const N: usize> {
#[serde(default)]

66
src/patterns/ring.rs Normal file
View File

@ -0,0 +1,66 @@
use crate::patterns::{Pattern, PixelColor};
use crate::Strip;
use serde::{Deserialize, Serialize};
/// # Ring
///
/// display a ring on the strip
#[derive(Serialize, Deserialize, Debug, Eq, Hash, PartialEq, Copy, Clone)]
pub struct Ring<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 Ring<N> {
type Strip = Strip<N>;
fn init(&mut self) -> Option<Self::Strip> {
None
}
fn is_last_iteration(&self) -> bool {
match self.max_iteration {
None => false,
Some(max_iter) => {
if self.current_iteration >= max_iter {
true
} else {
false
}
}
}
}
}
impl<const N: usize> Iterator for Ring<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;
let first_index = iter * self.ring_size;
let last_index = first_index + self.ring_size;
for i in first_index..last_index {
strip[i] = Some(self.color);
}
self.current_iteration += 1;
Some(strip)
}
}

View File

@ -0,0 +1,70 @@
use crate::patterns::{Pattern, PixelColor};
use crate::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>;
fn init(&mut self) -> Option<Self::Strip> {
None
}
fn is_last_iteration(&self) -> bool {
match self.max_iteration {
None => false,
Some(max_iter) => {
if self.current_iteration >= max_iter {
true
} else {
false
}
}
}
}
}
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)
}
}