Implement fixtures and library
This commit is contained in:
parent
60b2b56d8f
commit
1de834020a
@ -7,12 +7,13 @@
|
||||
import defaultCode from "./defaultCode.ts?raw";
|
||||
import defaultEnv from "./defaultEnv.d.ts?raw";
|
||||
import { code } from "./code";
|
||||
import tsOptions from "../eval/tsOptions";
|
||||
|
||||
let divEl: HTMLDivElement = null;
|
||||
let editor: monaco.editor.IStandaloneCodeEditor;
|
||||
|
||||
let value = defaultCode;
|
||||
$: $code = TS.transpile(value, { strict: true });
|
||||
$: $code = TS.transpile(value, tsOptions);
|
||||
|
||||
onMount(async () => {
|
||||
// @ts-ignore
|
||||
@ -30,7 +31,10 @@
|
||||
language: "typescript",
|
||||
});
|
||||
|
||||
let lib = monaco.languages.typescript.typescriptDefaults.addExtraLib(defaultEnv);
|
||||
let lib =
|
||||
monaco.languages.typescript.typescriptDefaults.addExtraLib(
|
||||
defaultEnv
|
||||
);
|
||||
|
||||
editor.onKeyUp((_e) => (value = editor.getValue()));
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { writable } from "svelte/store";
|
||||
import defaultCode from "./defaultCode.ts?raw";
|
||||
import TS from "typescript";
|
||||
import tsOptions from "../eval/tsOptions";
|
||||
|
||||
/** the transpiled JavaScript code */
|
||||
export const code = writable(TS.transpile(defaultCode, {strict: true}));
|
||||
export const code = writable(TS.transpile(defaultCode, tsOptions));
|
@ -1,4 +1,101 @@
|
||||
// ayaya ayaya
|
||||
// Connect the interface with the button below and modify the code here.
|
||||
// The output should update in real time as you type :)
|
||||
|
||||
ctx.set(1, 255);
|
||||
ctx.set(2, 255);
|
||||
// Fixtures library. TODO move this into a separate file
|
||||
|
||||
class Fixture {
|
||||
address: number
|
||||
ctx: Context
|
||||
|
||||
constructor(address: number, ctx: Context) {
|
||||
this.address = address;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
}
|
||||
|
||||
interface GenericRGBW {
|
||||
/**
|
||||
* Set the brightness
|
||||
*
|
||||
* @param value between 0 and 1
|
||||
* @param strobe enable strobe (turn off if unsupported)
|
||||
*/
|
||||
setBrightness(value: number, strobe?: boolean): void
|
||||
setRGBW(rgb: [number, number, number], w?: number): void
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
this.ctx.set(this.address, value * 255);
|
||||
this.ctx.set(this.address + 7, 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);
|
||||
}
|
||||
|
||||
setAUV(a: number, uv: number) {
|
||||
this.ctx.set(this.address + 5, a);
|
||||
this.ctx.set(this.address + 6, uv);
|
||||
}
|
||||
}
|
||||
|
||||
class MovingHead extends Fixture implements GenericRGBW {
|
||||
setBrightness(value: number, strobe?: boolean) {
|
||||
let out = (strobe || false)
|
||||
? 135 + (239 - 135) * value
|
||||
: 8 + (134 - 8) * value;
|
||||
this.ctx.set(this.address + 5, out);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the moving head. Pan and tilt are in radians.
|
||||
* @param pan between -1.5pi and 1.5pi
|
||||
* @param tilt between -0.5pi and 0.5pi
|
||||
* @param speed between 0 (fast) and 255 (slow)
|
||||
*/
|
||||
setPanTilt(pan: number, tilt: number, speed?: number) {
|
||||
let panRough = (pan + 3 * Math.PI / 2) / (Math.PI * 3) * 256
|
||||
panRough = Math.max(0, Math.min(255, panRough))
|
||||
|
||||
let tiltRough = (tilt + Math.PI / 2) / (Math.PI) * 256
|
||||
tiltRough = Math.max(0, Math.min(255, tiltRough))
|
||||
|
||||
// TODO
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// ******************
|
||||
// * CODE GOES HERE *
|
||||
// ******************
|
||||
|
||||
let color = lib.hsl2rgb(360 * t, 100, 50);
|
||||
|
||||
let par = new Par(1, ctx);
|
||||
par.setBrightness(1);
|
||||
par.setRGBW(color);
|
25
webserial/src/editor/defaultEnv.d.ts
vendored
25
webserial/src/editor/defaultEnv.d.ts
vendored
@ -1,9 +1,30 @@
|
||||
type Context = {
|
||||
/**
|
||||
* Set DMX address `address` to `value`
|
||||
* @param address between 1 and 511
|
||||
* @param value between 0 and 255
|
||||
*/
|
||||
set(address: number, value: number): void,
|
||||
};
|
||||
|
||||
/** the global Context object */
|
||||
/** The global Context object */
|
||||
declare const ctx: Context;
|
||||
|
||||
/** the current time (in seconds, e.g. 1.25 after 1250 milliseconds) */
|
||||
/** The current time (in seconds, e.g. 1.25 after 1250 milliseconds) */
|
||||
declare const t: number;
|
||||
|
||||
type Lib = {
|
||||
/**
|
||||
* Converts from the HSL color space to RGB
|
||||
*
|
||||
* Outputs [r, g, b] between 0 and 255 each
|
||||
*
|
||||
* @param h in degrees, i.e. 0 to 360
|
||||
* @param s between 0 and 100
|
||||
* @param l between 0 and 100
|
||||
*/
|
||||
hsl2rgb(h: number, s: number, l: number): [number, number, number]
|
||||
}
|
||||
|
||||
/** The standard library */
|
||||
declare const lib: Lib;
|
@ -3,14 +3,16 @@
|
||||
import { onMount } from "svelte";
|
||||
import { code } from "../editor/code";
|
||||
import { dmxData } from "../dmx/store";
|
||||
import { lib } from "./lib";
|
||||
|
||||
let startTime: number;
|
||||
let payload = new Uint8Array(512);
|
||||
let ctx: Context = {
|
||||
set(address: number, value: number) {
|
||||
payload[address - 1] = value;
|
||||
}
|
||||
}
|
||||
let rounded = Math.round(value);
|
||||
payload[address - 1] = Math.max(0, Math.min(255, rounded));
|
||||
},
|
||||
};
|
||||
|
||||
let result: string;
|
||||
|
||||
@ -18,7 +20,7 @@
|
||||
payload = new Uint8Array(512);
|
||||
const t = (performance.now() - startTime) / 1000;
|
||||
try {
|
||||
let ret = Function("ctx", "t", $code).call({}, ctx, t);
|
||||
let ret = Function("ctx", "t", "lib", $code).call({}, ctx, t, lib);
|
||||
result = JSON.stringify(ret);
|
||||
} catch (err) {
|
||||
result = JSON.stringify(err);
|
||||
@ -36,8 +38,8 @@
|
||||
|
||||
return () => {
|
||||
clearInterval(int);
|
||||
}
|
||||
})
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- <pre>{result}</pre> -->
|
16
webserial/src/eval/lib.ts
Normal file
16
webserial/src/eval/lib.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/// <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)];
|
||||
|
||||
},
|
||||
}
|
7
webserial/src/eval/tsOptions.ts
Normal file
7
webserial/src/eval/tsOptions.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import type { CompilerOptions } from "typescript"
|
||||
|
||||
const tsOptions: CompilerOptions = {
|
||||
strict: true
|
||||
}
|
||||
|
||||
export default tsOptions
|
@ -98,7 +98,11 @@
|
||||
if (loopTime < FRAME_TIME) {
|
||||
await sleep(FRAME_TIME - loopTime);
|
||||
} else {
|
||||
console.warn(`loop took too long (+${(loopTime - FRAME_TIME).toFixed(2)} ms)`);
|
||||
console.warn(
|
||||
`loop took too long (+${(loopTime - FRAME_TIME).toFixed(
|
||||
2
|
||||
)} ms)`
|
||||
);
|
||||
}
|
||||
lastLoopTime = loopTime;
|
||||
}
|
||||
|
@ -14,18 +14,23 @@
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#if navigator.serial}
|
||||
<p>Serial available 🚀</p>
|
||||
{#if port !== null}
|
||||
<SerialConnection {port}/>
|
||||
<p><button on:click={disconnect}>disconnect</button></p>
|
||||
{#if navigator.serial}
|
||||
<p>Serial available 🚀</p>
|
||||
{#if port !== null}
|
||||
<SerialConnection {port} />
|
||||
<p><button on:click={disconnect}>disconnect</button></p>
|
||||
{:else}
|
||||
<p><button on:click={connect}>connect</button></p>
|
||||
{/if}
|
||||
{:else}
|
||||
<p><button on:click={connect}>connect</button></p>
|
||||
<p>Looks like your browser does not support WebSerial 😢</p>
|
||||
<p>
|
||||
Check <a
|
||||
href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API#browser_compatibility"
|
||||
>here</a
|
||||
> for a list of compatible browsers
|
||||
</p>
|
||||
{/if}
|
||||
{:else}
|
||||
<p>Looks like your browser does not support WebSerial 😢</p>
|
||||
<p>Check <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API#browser_compatibility">here</a> for a list of compatible browsers</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
|
Loading…
Reference in New Issue
Block a user