ProControls requires p5.js. Add these three lines to your HTML <head> — the icons font
is optional but used by several controls. Load them in order: p5.js first, then ProControls.
<!-- Google icon font (optional — used by IconButton and nav icons) -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&display=block" rel="stylesheet">
<!-- p5.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/p5.min.js"></script>
<!-- ProControls (CDN) -->
<script src="https://cdn.jsdelivr.net/gh/dstein-art/proControls4p5js@v0.8.1/ProControls.js"></script>
<!-- Your sketch -->
<script src="sketch.js"></script>
ProControls.js from
GitHub
and change the src to a relative path if you prefer not to use the CDN.
Set ControlStyle once before creating any controls. Create controls in setup().
Call proControlBackground() at the top of draw() — controls render themselves
automatically after that via a built-in post hook. No event handlers needed.
// sketch.js
ControlStyle = 'black'; // set before creating any controls
// options: 'black' 'stainless' 'white' 'brushed'
// 'red' 'blue' 'yellow' 'dimpled'
let vol, pan, pwr;
function setup() {
createCanvas(600, 300);
vol = new AnalogSlider({ x: 40, y: 50, label: 'VOL' });
pan = new Dial({ x: 120, y: 60, label: 'PAN' });
pwr = new Switch({ x: 220, y: 80, label: 'PWR', states: ['OFF', 'ON'] });
}
function draw() {
proControlBackground(); // fills canvas with the style's background colour
// Controls draw themselves — nothing else needed here.
}
// Reading values anywhere in draw():
// vol.value → 0–1
// pan.value → 0–1
// pwr.state → 0 or 1
Leave out x and y and ProControls places the control automatically,
advancing the cursor based on each control's shape. Portrait controls tile left-to-right;
landscape controls stack top-to-bottom. When the column runs out of vertical space a new column starts.
// No coordinates — ProControls figures out where to put them.
const vol = new AnalogSlider();
const pan = new Dial();
const eq = new MultiSlider({ sliders: { 'LO': 0, 'MID': 0, 'HI': 0 } });
Call proControlReset() before rebuilding all controls — for example when the user
switches style. Read current values first to preserve them across the rebuild.
function buildControls() {
proControlReset(); // clear old registrations
ControlStyle = currentStyle;
mySlider = new AnalogSlider({ value: mySlider?.value ?? 0.5 });
}
mySlider.remove(); // deregisters from events; stop calling .draw() to remove visually
Every control inherits these from the ProControl base class.
| Option | Type | Default | Description |
|---|---|---|---|
| x | number | auto | Left edge of the control in canvas pixels. Omit to use auto-placement. |
| y | number | auto | Top edge of the control in canvas pixels. Omit to use auto-placement. |
| min | number | 0 | Minimum value of the range. |
| max | number | 1 | Maximum value of the range. |
| value | number | min | Initial value. Writable at any time via ctrl.value = v. |
| label | string | '' | Text label drawn on the control. |
| name | string | auto | Identifier used as a field key in composite controls (e.g. MultiSlider.values). Resolution order: (1) explicit name option, (2) label with spaces and punctuation removed ("My Freq" → "MyFreq"), (3) ClassName + auto-incrementing counter ("AnalogSlider1"). Readable and writable at any time via ctrl.name. |
| scale | string | 'linear' | 'linear' or 'log'. Log requires min > 0. Affects dragging, scrolling, and tick labels. |
| disabled | boolean | false | Draws a translucent overlay and blocks all interaction. |
| onChange | function | null | Called with the new value whenever it changes during interaction. |
| onRelease | function | null | Called once with the final value on mouse/touch release. |
| theme | object | {} | Partial theme override merged on top of the active style. See Themes & Styles. |
Every control inherits these from the ProControl base class.
| Method | Description |
|---|---|
.clone() | Returns a new independent copy of the control with all current options (value, min, max, label, theme, callbacks, etc.). For Panel, recursively clones all child controls and positions the copy adjacent to the original. |
Each tutorial walks through a family of controls step by step — from a one-line example to styling options and data callbacks. Every code block is live and editable directly in the browser.
AnalogSlider, Dial, MultiSlider, MultiDial, and RangeSlider — from a one-liner to spring-back handles, log scales, and live callbacks.
Start Tutorial → PadsXYPad and GridPad — touch surfaces, pressure zones, custom grid modes, and data callbacks.
Start Tutorial → SelectorsSwitch, IconButton, Selector, TagSelector, and SliderSelector — multi-state buttons, icon toggles, tag pickers, and blended controls.
Start Tutorial → PanelsPanel, Bevel, MessageDialog, and InputDialog — grouping controls, decorative separators, and modal dialogs.
Start Tutorial → MenusMenu and PopupMenu — menu bars, submenus, orientation options, and context menus at the cursor.
Start Tutorial → DisplaysVUMeter, VUDial, LEDMeter, ADSRDisplay, Markup, ConsolePanel, TimeGraphPanel, ListView, GridView, and HeatMapView — live data readouts, animated displays, and interactive data visualization.
Start Tutorial →