commit 0b6136b99e5974b174908de9a3bd00a8948bca23
parent df9fd70e935d842b8da4b8910bfc577e99df8fd5
Author: massi <mdsiboldi@gmail.com>
Date: Wed, 19 Jul 2023 03:43:45 -0700
add osc unit UI
Diffstat:
3 files changed, 105 insertions(+), 47 deletions(-)
diff --git a/src/lib/Osc.svelte b/src/lib/Osc.svelte
@@ -0,0 +1,67 @@
+<script lang="ts">
+ import type { OscUnit, WithTarget } from '$lib/types';
+ import { wrangle, rescale, range } from '$lib/types';
+ import NumberSelector from '$lib/NumberSelector.svelte';
+
+ export let unit: OscUnit;
+ export let updateOsc: (osc: OscUnit) => void;
+
+ $: vals = {
+ coarse:
+ typeof unit.coarse === 'number' ? wrangle(unit.coarse, range.signal, range.osc.coarse) : null,
+ fine: typeof unit.fine === 'number' ? wrangle(unit.fine, range.signal, range.osc.fine) : null,
+ superfine:
+ typeof unit.superfine === 'number'
+ ? wrangle(unit.superfine, range.signal, range.osc.superfine)
+ : null,
+ amount:
+ typeof unit.amount === 'number' ? wrangle(unit.amount, range.signal, range.osc.amount) : null
+ };
+
+ console.log({ vals });
+
+ const updateValue = (k: string, n: number) => {
+ updateOsc({ ...unit, [k]: Math.round(rescale(n, range.osc[k], range.signal)) });
+ };
+</script>
+
+<div class="unit-container">
+ <h3>{unit.kind}</h3>
+ {#each [...Object.entries(vals)] as [k, v]}
+ <div class="sect">
+ {#if v !== null}
+ <h3>{k}</h3>
+ <NumberSelector value={v} updateValue={updateValue.bind(undefined, k)} />
+ <input
+ name={unit.id}
+ type="range"
+ min={range.osc[k].min}
+ max={range.osc[k].max}
+ step={1}
+ value={v}
+ on:input={(e) => updateValue(k, Number(e.currentTarget?.value))}
+ />
+ {/if}
+ </div>
+ {/each}
+</div>
+
+<style>
+ .sect {
+ width: 100%;
+ height: 80px;
+ }
+ .disabled {
+ opacity: 0.5;
+ pointer-events: none;
+ }
+ .unit-container {
+ background: rgba(255, 255, 255, 0.3);
+ padding: 10px;
+ display: flexbox;
+ }
+ h3 {
+ padding: 0;
+ margin: 0;
+ }
+</style>
diff --git a/src/lib/types.ts b/src/lib/types.ts
@@ -39,7 +39,9 @@ export type Input = number | Output[];
export type Pos = { x: number; y: number };
-export type OscUnit = {
+type WithPos = { pos: Pos };
+
+export type OscUnit = WithPos & {
kind: "osc";
coarse: Input;
fine: Input;
@@ -47,16 +49,15 @@ export type OscUnit = {
amount: Input;
};
-export type NoiseUnit = {
+export type NoiseUnit = WithPos & {
kind: "noise";
amount: Input;
};
// outputs number as it is
-export type ConstUnit = {
+export type ConstUnit = WithPos & {
kind: "const";
value: number;
- pos: Pos;
};
export type UnitMap = Map<UnitId, Unit>;
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
@@ -2,6 +2,7 @@
import { onMount } from 'svelte';
import { debounce } from 'lodash';
import Sink from '$lib/Sink.svelte';
+ import Osc from '$lib/Osc.svelte';
import Slider from '$lib/Slider.svelte';
import { inp, ensure, rescale, range, is, getUnit as _getUnit } from '$lib/types';
import type { Output, Input, Unit, UnitId, ConstUnit, UnitMap, Sinks } from '$lib/types';
@@ -96,17 +97,11 @@
}
const updateUrl = debounce(_updateUrl, 250);
- function addUnit(unit: Unit): Input {
+ function addUnit(unit: Unit): UnitId {
const id = String(uid++);
units.set(id, unit);
units = units;
- return [{ id }];
- }
-
- type EzUnit = Input | number | undefined;
- // make a const unit or use the supplied one
- function ez(input: EzUnit): Input {
- return is.input(input) ? input : mk.c(input || randConst());
+ return id;
}
const randConst = () => {
@@ -115,29 +110,25 @@
};
const mk = {
- c: function mkConst(value?: number): Input {
+ c: function mkConst(): UnitId {
return addUnit({
kind: 'const',
- value: value == null ? randConst() : value,
+ value: randConst(),
pos: { x: 0, y: 0 }
});
},
- osc: function mkOsc(
- coarse?: EzUnit,
- fine?: EzUnit,
- superfine?: EzUnit,
- amount?: EzUnit
- ): Input {
+ osc: function mkOsc(): UnitId {
return addUnit({
kind: 'osc',
- coarse: ez(coarse),
- fine: ez(fine),
- superfine: superfine ? ez(superfine) : mk.c(0),
- amount: ez(amount)
+ coarse: randConst(),
+ fine: randConst(),
+ superfine: 0,
+ amount: randConst(),
+ pos: { x: 0, y: 0 }
});
},
- n: function noise(amt: EzUnit) {
- return addUnit({ kind: 'noise', amount: ez(amt) });
+ n: function noise(): UnitId {
+ return addUnit({ kind: 'noise', amount: randConst(), pos: { x: 0, y: 0 } });
}
};
@@ -155,16 +146,16 @@
units = units;
}
- const addConst = () => {
- addUnit({ kind: 'const', value: randConst(), pos: { x: 5, y: 5 } });
+ function updateEntireUnit(id: UnitId, unit: Unit) {
+ units.set(id, unit);
units = units;
- };
+ }
let dragging: false | UnitId = false;
const handleMouseMove = (e: MouseEvent) => {
if (!dragging) return;
- ensure.unit.const(getUnit(dragging)).pos = {
+ getUnit(dragging).pos = {
x: e.clientX,
y: e.clientY
};
@@ -186,17 +177,9 @@
let signalDragging: false | Output = false;
- const handleSignalStart = (obj: { id: UnitId }) => {
+ const handleSignalStart = (obj: Output) => {
console.log('signal start', obj);
- const unit = getUnit(obj.id);
- switch (unit.kind) {
- case 'const': {
- signalDragging = obj;
- break;
- }
- default:
- throw new Error('handleSignalStart nyi');
- }
+ signalDragging = obj;
};
const _onSinkConnect = (ch: 'l' | 'c' | 'h'): void => {
@@ -209,6 +192,10 @@
signalDragging = false;
};
+ $: {
+ console.log(units);
+ }
+
$: onSinkConnect = signalDragging ? _onSinkConnect : null;
$: unitEntries = units.entries();
@@ -221,7 +208,8 @@
<canvas bind:this={cvs} />
<div id="buttons">
- <button on:click={addConst}>add const</button>
+ <button on:click={mk.c}>add const</button>
+ <button on:click={mk.osc}>add osc</button>
</div>
<h1>HI {unitEntries}</h1>
@@ -232,12 +220,13 @@
</div>
<div id="units">
{#each [...unitEntries] as [id, unit]}
- <div
- class="unit"
- style={unit.kind === 'const' ? `top: ${unit.pos.y}px; left: ${unit.pos.x}px` : ''}
- >
+ <div class="unit" style={`top: ${unit.pos.y}px; left: ${unit.pos.x}px`}>
<h2 on:mousedown={handleMouseDown.bind(null, id)}>{id} {unit.kind}</h2>
- <Slider {id} {units} handleInput={updateUnit} handleChange={updateUrl} />
+ {#if unit.kind === 'const'}
+ <Slider {id} {units} handleInput={updateUnit} handleChange={updateUrl} />
+ {:else if unit.kind === 'osc'}
+ <Osc {unit} updateOsc={updateEntireUnit.bind(null, id)} />
+ {/if}
<div
class="output-dragger"
on:mousedown={(e) => {
@@ -254,7 +243,7 @@
position: absolute;
top: 0;
bottom: 0;
- right: 0;
+ right: -20px;
width: 20px;
background: purple;
}
@@ -266,6 +255,7 @@
flex-direction: column;
}
.unit {
+ width: 150px;
position: absolute;
z-index: 1;
background: black;