Two browser APIs turn a plain web page into a creative instrument: Canvas 2D for pixels and the Web Audio API for sound. Together they cover generative art, data visualization, music tools, games, and accessible audio feedback. This guide is hands-on — every snippet runs if you paste it into NitroIDE's preview.
Canvas is immediate-mode: you issue draw commands, pixels appear. No scene graph, no retained objects — which makes it blazing fast for custom rendering:
Crisp on every screen: canvas looks blurry on high-DPI displays unless you scale it. Multiply canvas.width/height by devicePixelRatio and call ctx.scale(devicePixelRatio, devicePixelRatio) — one of the most common canvas bugs, fixed in two lines.
Canvas text rendering is notoriously rough compared to DOM text. Practical fixes: always set an explicit ctx.font (don't rely on the 10px default), enable ctx.textBaseline deliberately, and for editor-grade typography consider shaping text properly — libraries like HarfBuzz compiled to WASM exist precisely because complex scripts need real text shaping, which canvas won't do for you.
The Web Audio API is a graph of nodes: sources → effects → destination. Building a playable synth takes surprisingly little code:
That envelope — quick attack, exponential decay — is what separates "beep" from "instrument." Everything is scheduled on the audio clock (ctx.currentTime), which is sample-accurate and independent of frame rate.
For custom DSP — a distortion effect, a granular sampler, a metronome that never drifts — you need code running on the audio thread itself. AudioWorklet replaced the old (now removed) ScriptProcessorNode:
Because this runs on the audio rendering thread, timing is sample-accurate — no setInterval drift. Keep the process() method lean: no allocations, no async work, or you'll hear glitches.
Sound isn't just for music apps. Short, subtle audio cues — a soft tick on toggle, a rising pitch as a progress bar fills — give non-visual feedback that helps everyone, including screen-reader users navigating custom controls. The Web Audio snippets above are all you need; keep cues under 200 ms and always respect prefers-reduced-motion-style user preferences for sound where your app offers a mute.
The one rule of web audio: AudioContext starts suspended until a user gesture. Always create or resume it inside a click/keydown handler — otherwise you'll debug silence for an hour. This is a browser autoplay policy, not a bug in your code.
Creative coding needs instant feedback — get it in a zero-setup browser IDE.
Launch NitroIDE