Add flashing pattern

This commit is contained in:
Austen Adler 2021-08-15 14:53:11 -04:00
parent ea30e00eba
commit 5dc0438dd8
3 changed files with 132 additions and 45 deletions

53
src/pattern/flashing.rs Normal file
View File

@ -0,0 +1,53 @@
use super::Pattern;
use crate::color::{self, Rgb};
use std::{
collections::{vec_deque, VecDeque},
convert::TryFrom,
iter,
};
#[derive(Clone, Debug)]
pub struct Flashing {
lights_buf: VecDeque<Rgb>,
width: u8,
colors: Vec<Rgb>,
}
impl Flashing {
pub fn new(colors: Vec<Rgb>, width: u8) -> Self {
Self {
colors,
width,
lights_buf: VecDeque::new(),
}
}
}
impl Pattern for Flashing {
fn step(&mut self) -> Result<bool, ()> {
self.lights_buf.rotate_right(self.width.into());
Ok(true)
}
fn init(&mut self, num_lights: u16) -> Result<(), ()> {
if self.lights_buf.len() == 0 {
return Err(());
}
let length_factor = u16::try_from(self.lights_buf.len())
.or(Err(()))?
.saturating_mul(u16::from(self.width));
let buf_length = color::min_with_factor(num_lights, length_factor)?;
self.lights_buf = self
.colors
.iter()
.flat_map(|&x| iter::repeat(x).take(self.width.into()))
.cycle()
.take(buf_length.into())
.collect();
Ok(())
}
fn get_strip(&self) -> vec_deque::Iter<Rgb> {
self.lights_buf.iter()
}
}

22
web/src/Colors.svelte Normal file
View File

@ -0,0 +1,22 @@
<script lang="ts">
// From: https://css-tricks.com/snippets/javascript/random-hex-color/
function randomColor() {
return "#" + Math.floor(Math.random()*16777215).toString(16);
}
export let value = [randomColor()];
function newColor() {
console.log(value);
value = [...value, randomColor()];
}
function removeColor() {
if(newColor.length > 1) {
value = value.slice(0, -1);
}
}
</script>
{#each value as value}
<input type="color" bind:value={value} />
{/each}
<button type="button" on:click={newColor} href="#">+</button>
<button type="button" on:click={removeColor} href="#">-</button>

View File

@ -1,4 +1,6 @@
<script lang="ts">
import Colors from "./Colors.svelte";
let url = "/api/setcolor";
let possiblePatterns = [
{name: "Solid", text: "Solid", formElements: [
@ -25,11 +27,12 @@
{name: "backoff_width", type: "number", label: "Backoff Width", value: "0"},
]},
{name: "Flashing", text: "Flashing", formElements: [
{name: "color", type: "color", label: "Color1", value: "#000000"},
{name: "color", type: "color", label: "Color2", value: "#000000"},
{name: "color", type: "color", label: "Color3", value: "#000000"},
{name: "color", type: "color", label: "Color4", value: "#000000"},
{name: "color", type: "color", label: "Color5", value: "#000000"},
{name: "color", type: "colors", label: "Color", value: []},
// {name: "color", type: "color", label: "Color1", value: "#000000"},
// {name: "color", type: "color", label: "Color2", value: "#000000"},
// {name: "color", type: "color", label: "Color3", value: "#000000"},
// {name: "color", type: "color", label: "Color4", value: "#000000"},
// {name: "color", type: "color", label: "Color5", value: "#000000"},
{name: "width", type: "number", label: "Width", value: "1"},
]},
];
@ -37,7 +40,8 @@
function hexToRgb(hex) {
// Adapted from https://stackoverflow.com/a/5624139
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
var result = /^#?([a-f\d]{1,2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
console.log(hex);
result.splice(0, 1);
return result ? result.map(r => parseInt(r, 16)) : null;
}
@ -55,6 +59,10 @@
case "checkbox":
return x.value === "on";
break;
case "colors":
console.log(x);
return x.value.map(hexToRgb);
break;
default:
return x.value;
}
@ -81,7 +89,11 @@
</select>
{#each selectedPattern.formElements as fe}
<label for={fe.name}>{fe.label}</label>
{#if fe.type === "colors"}
<Colors bind:value={fe.value}/>
{:else}
<input type={fe.type} name={fe.name} on:input={(e) => fe.value = e.target.value} />
{/if}
{/each}
<button type="submit">Submit</button>
</form>