color-synth

a synth that generates colors instead of sounds
Log | Files | Refs | README

stores.ts (3215B)


      1 import {
      2 	rescale,
      3 	type ControlName,
      4 	type Controls,
      5 	type Input,
      6 	type Unit,
      7 	type UnitId,
      8 	type UnitKind,
      9 	type UnitToConnect,
     10 	type Units,
     11 	RANGE,
     12 	wrangle,
     13 	unitRange,
     14 	type Pos,
     15 	type Sinks
     16 } from '$lib/types';
     17 import { v4 as uuidv4 } from 'uuid';
     18 
     19 import { writable } from 'svelte/store';
     20 
     21 const randNum = () => {
     22 	const sliderVal = Math.round(rescale(Math.random(), { min: 0, max: 1 }, RANGE.slider));
     23 	return rescale(sliderVal, RANGE.slider, RANGE.signal);
     24 };
     25 
     26 const mkInput = (value?: number) => {
     27 	const ret: Input = { sources: [] };
     28 	if (value !== undefined) {
     29 		ret.value = value;
     30 	}
     31 	return ret;
     32 };
     33 
     34 const mkUnitStore = () => {
     35 	const { subscribe, set, update } = writable<Units>({});
     36 	const setControl = <K extends UnitKind>(
     37 		kind: K,
     38 		id: UnitId,
     39 		controlName: ControlName<K>,
     40 		input: Input
     41 	) => {
     42 		update((units) => {
     43 			const controls = units[id].controls as Controls<K>;
     44 			controls[controlName] = input;
     45 			return units;
     46 		});
     47 	};
     48 	return {
     49 		subscribe,
     50 		set,
     51 		setUnit<K extends UnitKind>(id: UnitId, unit: Unit<K>) {
     52 			update((units) => ({ ...units, [id]: unit }));
     53 		},
     54 		setControl,
     55 		addUnit<K extends UnitKind>(kind: K): UnitId {
     56 			let unit: Unit;
     57 			switch (kind) {
     58 				case 'number': {
     59 					unit = { kind: 'number', controls: { value: mkInput(0) }, pos: { x: 0, y: 0 } };
     60 					break;
     61 				}
     62 				case 'osc': {
     63 					unit = {
     64 						kind: 'osc',
     65 						controls: {
     66 							coarse: mkInput(wrangle(1, unitRange.osc.coarse, RANGE.signal)),
     67 							fine: mkInput(wrangle(1, unitRange.osc.fine, RANGE.signal)),
     68 							superfine: mkInput(0),
     69 							amount: mkInput(RANGE.signal.max),
     70 							waveshape: mkInput(RANGE.signal.min)
     71 						},
     72 						pos: { x: 0, y: 0 }
     73 					};
     74 					break;
     75 				}
     76 				case 'noise': {
     77 					unit = {
     78 						kind: 'noise',
     79 						controls: { amount: mkInput(RANGE.signal.max / 2) },
     80 						pos: { x: 0, y: 0 }
     81 					};
     82 					break;
     83 				}
     84 				case 'smooth': {
     85 					unit = {
     86 						kind: 'smooth',
     87 						controls: {
     88 							frames: mkInput(wrangle(3, unitRange.smooth.frames, RANGE.signal)),
     89 							signal: mkInput()
     90 						},
     91 						pos: { x: 0, y: 0 }
     92 					};
     93 					break;
     94 				}
     95 				case 'math': {
     96 					unit = {
     97 						kind: 'math',
     98 						controls: {
     99 							a: mkInput(0),
    100 							op: mkInput(RANGE.signal.min),
    101 							b: mkInput(0)
    102 						},
    103 						pos: { x: 0, y: 0 }
    104 					};
    105 					break;
    106 				}
    107 				case 'lag': {
    108 					unit = {
    109 						kind: 'lag',
    110 						controls: {
    111 							signal: mkInput(),
    112 							amount: mkInput(0)
    113 						},
    114 						pos: { x: 0, y: 0 }
    115 					};
    116 					break;
    117 				}
    118 				case 'img': {
    119 					unit = {
    120 						kind: 'img',
    121 						controls: {
    122 							speed: mkInput(rescale(100000, unitRange.img.speed, RANGE.signal))
    123 						},
    124 						pos: { x: 0, y: 0 }
    125 					};
    126 				}
    127 			}
    128 
    129 			const uuid = uuidv4();
    130 			update((units) => {
    131 				return { ...units, [uuid]: unit };
    132 			});
    133 			return String(uuid);
    134 		}
    135 	};
    136 };
    137 
    138 export const unitToConnect = writable<UnitToConnect>(false);
    139 
    140 export type UnitDragging = null | { initPos: Pos; pos: Pos; id: UnitId };
    141 export const unitDragging = writable<UnitDragging>(null);
    142 
    143 export const unitStore = mkUnitStore();
    144 export const sinksStore = writable<Sinks>({
    145 	l: { value: 0, sources: [] },
    146 	c: { value: 0, sources: [] },
    147 	h: { value: 0, sources: [] }
    148 });