p5.js Intermediate Article 7

DOM Manipulation

Build UI controls alongside your canvas — sliders, buttons, dropdowns, and custom HTML — using p5.dom.

⏱ 18 min read DOM UI slider button HTML createDiv

p5.js and the DOM

p5.js can create and manipulate HTML elements directly. This is useful for building control panels, adding labels, or integrating a sketch into a larger page.

Creating basic UI elements

let slider, btn, sel;

function setup() {
  createCanvas(600, 400);

  // Slider: min, max, default, step
  slider = createSlider(0, 255, 128, 1);
  slider.position(10, height + 20);
  slider.style('width', '200px');

  // Button
  btn = createButton('Randomise');
  btn.position(220, height + 16);
  btn.mousePressed(randomise);

  // Dropdown
  sel = createSelect();
  sel.position(10, height + 55);
  sel.option('Circles');
  sel.option('Squares');
  sel.option('Triangles');
}

function draw() {
  background(slider.value());  // use slider value
  drawShapes();
}

function randomise() {
  // do something
}

Styling elements

Use .style() to apply CSS:

btn.style('background', '#7c6af7');
btn.style('color', '#fff');
btn.style('border', 'none');
btn.style('padding', '8px 16px');
btn.style('border-radius', '6px');
btn.style('cursor', 'pointer');
btn.style('font-size', '14px');

Or use .class() and write CSS in a stylesheet:

btn.class('my-btn');

Input and text area

let input = createInput('default text');
input.position(10, height + 90);
input.size(300);

let ta = createElement('textarea');
ta.position(10, height + 120);
ta.size(300, 80);

Read values:

let val = input.value();
let text = ta.value();

Listen for changes:

input.input(function() {
  print('Input changed:', this.value());
});

Checkbox and radio

let checkbox = createCheckbox('Show grid', true);
checkbox.position(10, height + 100);
checkbox.changed(function() {
  showGrid = this.checked();
});

// Radio buttons
let r1 = createRadio();
r1.option('option1', 'Value A');
r1.option('option2', 'Value B');
r1.value('option1');  // set default
r1.position(10, height + 130);

Placing elements inside the canvas area

Use .parent() to attach an element to a container div:

<div id="sketch-container">
  <div id="controls"></div>
</div>
function setup() {
  let canvas = createCanvas(600, 400);
  canvas.parent('sketch-container');

  let slider = createSlider(0, 100, 50);
  slider.parent('controls');
}

Dynamic HTML content

// Create a div and set its HTML
let panel = createDiv('');
panel.html('<h3>Stats</h3>');
panel.position(620, 20);
panel.style('color', 'white');
panel.style('width', '180px');

// Update each frame
function draw() {
  // ...
  panel.html(`
    <b>FPS:</b> ${floor(frameRate())}<br>
    <b>Particles:</b> ${particles.length}
  `);
}

Removing elements

btn.remove();       // remove a specific element
removeElements();   // remove all p5-created elements (not the canvas)

A full control panel example

let params = {
  speed:     2,
  numBalls:  30,
  mode:      'bounce',
  showTrail: true
};

function setup() {
  let canvas = createCanvas(700, 500);
  canvas.parent('sketch');

  buildControls();
  initBalls();
}

function buildControls() {
  let panel = createDiv('');
  panel.parent('controls');
  panel.style('display', 'flex');
  panel.style('flex-direction', 'column');
  panel.style('gap', '12px');
  panel.style('padding', '16px');

  // Speed slider
  let speedLabel = createP('Speed');
  speedLabel.parent(panel);
  let speedSlider = createSlider(0.5, 8, params.speed, 0.1);
  speedSlider.parent(panel);
  speedSlider.input(() => params.speed = speedSlider.value());

  // Number of balls
  let numLabel = createP('Balls');
  numLabel.parent(panel);
  let numSlider = createSlider(1, 100, params.numBalls, 1);
  numSlider.parent(panel);
  numSlider.input(() => {
    params.numBalls = numSlider.value();
    initBalls();
  });

  // Mode select
  let modeLabel = createP('Mode');
  modeLabel.parent(panel);
  let modeSelect = createSelect();
  modeSelect.parent(panel);
  ['bounce', 'wrap', 'orbit'].forEach(m => modeSelect.option(m));
  modeSelect.changed(() => params.mode = modeSelect.value());

  // Trail checkbox
  let trailCheck = createCheckbox('Show trail', params.showTrail);
  trailCheck.parent(panel);
  trailCheck.changed(function() { params.showTrail = this.checked(); });
}

Key takeaways

  • createSlider(), createButton(), createSelect() etc. create HTML elements alongside the canvas
  • .style() applies CSS inline; .class() attaches a CSS class
  • .parent(id) places an element inside a specific container
  • .value() reads the current value; .input() and .changed() fire on updates
  • Update dynamic text panels in draw() using .html()
  • removeElements() cleans up all p5-created HTML elements at once