Add flashing pattern
This commit is contained in:
parent
ea30e00eba
commit
5dc0438dd8
53
src/pattern/flashing.rs
Normal file
53
src/pattern/flashing.rs
Normal 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
22
web/src/Colors.svelte
Normal 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>
|
@ -1,4 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import Colors from "./Colors.svelte";
|
||||||
|
|
||||||
let url = "/api/setcolor";
|
let url = "/api/setcolor";
|
||||||
let possiblePatterns = [
|
let possiblePatterns = [
|
||||||
{name: "Solid", text: "Solid", formElements: [
|
{name: "Solid", text: "Solid", formElements: [
|
||||||
@ -25,11 +27,12 @@
|
|||||||
{name: "backoff_width", type: "number", label: "Backoff Width", value: "0"},
|
{name: "backoff_width", type: "number", label: "Backoff Width", value: "0"},
|
||||||
]},
|
]},
|
||||||
{name: "Flashing", text: "Flashing", formElements: [
|
{name: "Flashing", text: "Flashing", formElements: [
|
||||||
{name: "color", type: "color", label: "Color1", value: "#000000"},
|
{name: "color", type: "colors", label: "Color", value: []},
|
||||||
{name: "color", type: "color", label: "Color2", value: "#000000"},
|
// {name: "color", type: "color", label: "Color1", value: "#000000"},
|
||||||
{name: "color", type: "color", label: "Color3", value: "#000000"},
|
// {name: "color", type: "color", label: "Color2", value: "#000000"},
|
||||||
{name: "color", type: "color", label: "Color4", value: "#000000"},
|
// {name: "color", type: "color", label: "Color3", value: "#000000"},
|
||||||
{name: "color", type: "color", label: "Color5", 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"},
|
{name: "width", type: "number", label: "Width", value: "1"},
|
||||||
]},
|
]},
|
||||||
];
|
];
|
||||||
@ -37,7 +40,8 @@
|
|||||||
|
|
||||||
function hexToRgb(hex) {
|
function hexToRgb(hex) {
|
||||||
// Adapted from https://stackoverflow.com/a/5624139
|
// 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);
|
result.splice(0, 1);
|
||||||
return result ? result.map(r => parseInt(r, 16)) : null;
|
return result ? result.map(r => parseInt(r, 16)) : null;
|
||||||
}
|
}
|
||||||
@ -55,6 +59,10 @@
|
|||||||
case "checkbox":
|
case "checkbox":
|
||||||
return x.value === "on";
|
return x.value === "on";
|
||||||
break;
|
break;
|
||||||
|
case "colors":
|
||||||
|
console.log(x);
|
||||||
|
return x.value.map(hexToRgb);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return x.value;
|
return x.value;
|
||||||
}
|
}
|
||||||
@ -81,7 +89,11 @@
|
|||||||
</select>
|
</select>
|
||||||
{#each selectedPattern.formElements as fe}
|
{#each selectedPattern.formElements as fe}
|
||||||
<label for={fe.name}>{fe.label}</label>
|
<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} />
|
<input type={fe.type} name={fe.name} on:input={(e) => fe.value = e.target.value} />
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
<button type="submit">Submit</button>
|
<button type="submit">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
|
Loading…
Reference in New Issue
Block a user