ui-builder.js — UI Components
Generates the per-module parameter control cards, handles canvas drawing for waveform and envelope visualisation, and synchronises lock states.
Module Sections
buildModuleSection(container, mod, params, lockedParams, onChange)
Creates a card for one module. Each card contains:
┌─────────────────────────────────────────────┐
│ Module Label [🔓] [🎲] ┌──────────┐ │
│ Param Label ═══●═════ val [🔓] │ canvas │
│ Param Label ══○═══════ val [🔓] │ (if │
│ ... │ mod. │
│ │canvasId│
│ └────────┘ │
└─────────────────────────────────────────────┘
- Section lock button (🔓/🔒) toggles all params in that section
- Randomise button (🎲) randomises unlocked params and calls
onChange - Each param row has label, control (range/select/checkbox), value display, lock
- Optional inline canvas to the right of controls when
mod.canvasIdis set. Setmod.canvasExternal = trueto suppress inline canvas creation — the canvas is placed in the HTML template instead and drawn bydoRender()via its ID.
Supports three control types:
- type: 'range' → <input type="range"> + value <span>
- type: 'select' → <select> with options
- type: 'checkbox' → <input type="checkbox">
For select params, set ui: 'pills' to render the options as clickable
pill buttons instead of a dropdown:
pitchCurve: { type: 'select', options: ['exponential', 'linear'], default: 'exponential', label: 'Curve', ui: 'pills' }
syncModuleUI(container, modules, params)
Syncs UI controls ([data-key] elements) with current param values. Used after
randomise or preset/template load. Builds a param-def lookup from modules for
proper formatValue rendering (units, note names).
syncLockUI(container, lockedParams)
Updates all per-param lock buttons ([data-lock-key]) and section lock buttons
(.section-lock) to reflect the current lockedParams state. Used when
a template is applied or locks are cleared programmatically.
Canvas Drawing
drawEnvelopeCurve(c, fn, colour)
Draws a normalised envelope curve on a 2D canvas context. fn(t) receives t
in [0, 1] and returns a value in [0, 1]. The curve is drawn with:
- Theme-aware background (dark/light)
- Light horizontal grid lines
- Filled area under the curve at reduced opacity
- Stroked curve at full opacity
- "time" label at bottom-right
drawWaveform(c, samples)
Draws a PCM waveform as a centred line graph. samples is a Float32Array.
Down-samples to match canvas width. Theme colours are applied by the caller.
isDarkTheme() → boolean
Returns true when data-bs-theme attribute is "dark".
formatValue(pd, val) → string
Formats a param value using its definition:
- Appends unit string (Hz, s, dB) where present
- Hz values show nearest note: "220 Hz (A3)"
- Non-unit values get 2 decimal places
- Log-scale Hz params (marked log: true) show 2 decimal places for fine
control at low rates (e.g. "0.75 Hz")
Slider types
| Property | Effect |
|---|---|
log: true |
Maps slider position logarithmically for fine control at low end of range |
step: <number> |
Explicit step size (default: (max-min)/200) |