Refactor default code, Improve stdlib, Implement Flower

This commit is contained in:
Kai Vogelgesang 2022-12-29 15:15:59 +01:00
parent 85ea070632
commit 162103e54b
Signed by: kai
GPG Key ID: 3FC8578CC818A9EB
3 changed files with 124 additions and 40 deletions

View File

@ -4,12 +4,19 @@
// Fixtures library. TODO move this into a separate file
class Fixture {
address: number
ctx: Context
startAddress: number
constructor(address: number, ctx: Context) {
this.address = address;
this.ctx = ctx;
constructor(startAddress: number) {
this.startAddress = startAddress;
}
/**
* Write to a DMX channel
* @param address Address offset (1 = start address)
* @param value between 0 and 255
*/
setChannel(address: number, value: number) {
ctx.set(this.startAddress + address - 1, value);
}
}
@ -27,42 +34,43 @@ interface GenericRGBW {
class Par extends Fixture implements GenericRGBW {
setBrightness(value: number, strobe?: boolean) {
if (strobe || false) {
this.ctx.set(this.address, 255);
this.ctx.set(this.address + 7, value * 255);
this.setChannel(1, 255);
this.setChannel(8, value * 255);
} else {
this.ctx.set(this.address, value * 255);
this.ctx.set(this.address + 7, 0);
this.setChannel(1, value * 255);
this.setChannel(8, 0);
}
}
setRGBW(rgb: [number, number, number], w?: number) {
let [r, g, b] = rgb;
this.ctx.set(this.address + 1, r);
this.ctx.set(this.address + 2, g);
this.ctx.set(this.address + 3, b);
this.ctx.set(this.address + 4, w || 0);
this.setChannel(2, r);
this.setChannel(3, g);
this.setChannel(4, b);
this.setChannel(5, w || 0);
}
setAUV(a: number, uv: number) {
this.ctx.set(this.address + 5, a);
this.ctx.set(this.address + 6, uv);
this.setChannel(6, a);
this.setChannel(7, uv);
}
}
class MovingHead extends Fixture implements GenericRGBW {
setBrightness(value: number, strobe?: boolean) {
let out = (strobe || false)
let val = (strobe || false)
? 135 + (239 - 135) * value
: 8 + (134 - 8) * value;
this.ctx.set(this.address + 5, out);
this.setChannel(6, val);
}
setRGBW(rgb: [number, number, number], w?: number) {
let [r, g, b] = rgb;
this.ctx.set(this.address + 6, r);
this.ctx.set(this.address + 7, g);
this.ctx.set(this.address + 8, b);
this.ctx.set(this.address + 9, w || 0);
this.setChannel(7, r);
this.setChannel(8, g);
this.setChannel(9, b);
this.setChannel(10, w || 0);
}
/**
@ -82,20 +90,59 @@ class MovingHead extends Fixture implements GenericRGBW {
let panFine = 0
let tiltFine = 0
this.ctx.set(this.address + 0, panRough);
this.ctx.set(this.address + 1, panFine);
this.ctx.set(this.address + 2, tiltRough);
this.ctx.set(this.address + 3, tiltFine);
this.ctx.set(this.address + 4, speed || 0);
this.setChannel(1, panRough);
this.setChannel(2, panFine);
this.setChannel(3, tiltRough);
this.setChannel(4, tiltFine);
this.setChannel(5, speed || 0);
}
}
class Flower extends Fixture implements GenericRGBW {
setBrightness(value: number, strobe?: boolean): void {
// dimmer seems unsupported :(
this.setChannel(7, (strobe || false) ? 255 * value : 0);
}
setRGBW(rgb: [number, number, number], w?: number): void {
const [r, g, b] = rgb;
this.setChannel(1, r);
this.setChannel(2, g);
this.setChannel(3, b);
this.setChannel(4, w || 0);
}
setAP(a: number, p: number) {
this.setChannel(5, a);
this.setChannel(6, p);
}
/**
* Set the rotation speed
* @param speed Between -1 (clockwise) and 1 (counterclockwise)
*/
setRotation(direction: number) {
const val = (direction < 0)
? /* clockwise */ lib.remap(direction, [0, -1], [0, 128], true)
: /* counterclockwise */ lib.remap(direction, [0, 1], [129, 255], true);
this.setChannel(8, val);
}
setMacro(pattern: number, speed: number) {
this.setChannel(9, pattern);
this.setChannel(10, speed);
}
}
// ******************
// * CODE GOES HERE *
// ******************
let color = lib.hsl2rgb(360 * t, 100, 50);
let par = new Par(1, ctx);
let par = new Par(1);
par.setBrightness(1);
par.setRGBW(color);

View File

@ -23,7 +23,18 @@ type Lib = {
* @param s between 0 and 100
* @param l between 0 and 100
*/
hsl2rgb(h: number, s: number, l: number): [number, number, number]
hsl2rgb(h: number, s: number, l: number): [number, number, number],
clamp(value: number, boundaries: [number, number]),
/**
* Map a value from one range to the other
* @param value to be remapped. Does not need to be in the source range.
* @param from [lower, upper] boundaries of source range.
* @param to [lower, upper] boundaries of target range.
* @param clamp clamp the output to the target range boundaries
*/
remap(value: number, from: [number, number], to: [number, number], clamp?: boolean),
}
/** The standard library */

View File

@ -1,16 +1,42 @@
/// <reference path="../editor/defaultEnv.d.ts" />
export const lib: Lib = {
hsl2rgb(h, s, l): [number, number, number] {
// https://stackoverflow.com/a/44134328
l /= 100;
const a = s * Math.min(l, 1 - l) / 100;
const f = n => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color)
};
return [f(0), f(8), f(4)];
function hsl2rgb(h, s, l): [number, number, number] {
// https://stackoverflow.com/a/44134328
l /= 100;
const a = s * Math.min(l, 1 - l) / 100;
const f = n => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color)
};
return [f(0), f(8), f(4)];
},
}
function clamp(value: number, boundaries: [number, number]) {
let [l, r] = boundaries;
return Math.max(l, Math.min(value, r));
}
const _clamp = clamp;
function remap(value: number, from: [number, number], to: [number, number], clamp?: boolean) {
const [a, b] = from;
const normalized = (value - a) / (b - a);
const [c, d] = to;
let remapped = c + (d - c) * normalized;
if (clamp) {
remapped = _clamp(remapped, to)
};
return remapped;
}
export const lib: Lib = {
hsl2rgb: hsl2rgb,
clamp: clamp,
remap: remap,
}