Refactor default code, Improve stdlib, Implement Flower
This commit is contained in:
parent
85ea070632
commit
162103e54b
@ -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);
|
13
webserial/src/editor/defaultEnv.d.ts
vendored
13
webserial/src/editor/defaultEnv.d.ts
vendored
@ -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 */
|
||||
|
@ -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,
|
||||
}
|
Loading…
Reference in New Issue
Block a user