Draw your own canvas
Paint a fully custom, live visual.When the built-in displays aren't enough, draw the device's face yourself. You get a blank canvas and the usual drawing commands (rectangles, circles, lines, text, gradients, images), redrawn every frame. Full command list in the canvas API reference.
Declare a canvas in ui.ts
Give it a name and list what it needs to draw.
Canvas({
id: "viz",
width: "fill",
height: Theme.sizing(20),
inputs: [param("amount"), channel("spectrum"), Theme.colors.accent],
});Draw it in a paint file
Make canvases/viz/paint.ts. A spectrum, one bar per frequency:
definePaint((p: Paint): void => {
const bins = p.channelLen(1); // input 1: the spectrum
for (let i = 0; i < bins; i++) {
const v = p.channel(1, i); // bar height, 0 to 1
p.fillStyle(p.color(2, 0), p.color(2, 1), p.color(2, 2), p.color(2, 3));
p.fillRect(<f32>i, p.height * (1 - v), 1, p.height * v);
}
});Inputs read by position: p.scalar(0) for the first, p.channel(1, ...) for the
second, p.color(2, ...) for the third.
Make it interactive
Mark parts of the drawing as touchable without drawing controls yourself, all declared
next to the Canvas as rects in canvas fractions (0..1):
- A
hitsregion is a drag zone: it acts like a hidden knob bound to a param, with the modulation wheel. - A
clicksregion is a click zone: a click toggles, sets, or cycles its param, good for a step grid. - A
commandsregion dispatchesonCommandto your DSP instead of touching a param, for stateful UIs like a note matrix. See Respond to clicks.
Details in the canvas API reference.
Want it on the GPU instead? A shader can draw the canvas in a fragment program: see Draw with a shader.