Document Object Model

This week we're going to add HTML elements to our p5 project to create a user interface using common components from HTML.

Of course, we can add HTML and CSS to our projects in the traditional manner by editing index.html or style.css, but p5 also has functions to create the elements from the sketch.js file to keep our work in one place.

These function are part of the DOM (Document Object Model) library, which is now a default part of p5.

Button

We can create a new function to actually draw the pattern. Then the user can click the button to generate new patterns.

function setup() { createCanvas(640, 360); pattern(); // generate a pattern to start var patternButton = createButton('New Pattern'); patternButton.mousePressed(pattern); } function pattern() { background('plum'); noStroke(); fill('lightblue'); for (let x = 0; x <= width; x += 50) { ellipse(x, random(height), random(100)); } }

Let's add another button.

For this one, let's add a button for the user to save an image.

function setup() { createCanvas(640, 360); noStroke(); pattern(); // generate a pattern to start var patternButton = createButton('New Pattern'); patternButton.mousePressed(pattern); var saveButton = createButton('Save Image'); saveButton.mousePressed(saveImage); } function saveImage() { save('pattern.png'); } function pattern() { background('plum'); fill('lightblue'); for (let x = 0; x <= width; x += 50) { ellipse(x, random(height), random(100)); } }

Changing the pattern

We can use buttons to change the values that determine how our pattern looks.

var angle = 0; function setup() { createCanvas(640, 360); noStroke(); pattern(); // generate a pattern to start var rotateButton = createButton('New Pattern'); rotateButton.mousePressed(updatePattern); } function updatePattern() { angle += 0.1 * PI; pattern(); } function pattern() { background('plum'); fill('lightblue'); for (let x = 0; x <= width; x += 50) { push(); translate(x, height/2); rotate(angle); rect(0, 0, random(100), random(100)); pop(); } }

More HTML

In this example using a slider, we'll use the rotateSlider to give the user more control over the rotation.

var rotateSlider; function setup() { createCanvas(640, 360); noStroke(); rotateSlider = createSlider(0, TWO_PI, 0); rotateSlider.input(pattern); pattern(); // generate a pattern to start } function pattern() { background('plum'); fill('lightblue'); for (let x = 0; x <= width; x += 50) { push(); translate(x, height/2); rotate(rotateSlider.value()); rect(0, 0, random(100), random(100)); pop(); } }

Using HTML form input is another way to let the user interact with our sketch. We can also take input in the form of text.

In this example using a text input, we need the nameInput variable to keep track of the user input.

var nameInput; function setup() { var canvas = createCanvas(640, 360); canvas.drawingContext.miterLimit = 2; nameInput = createInput("Type here"); textSize(100); textAlign(CENTER, CENTER); } function draw(){ background(0); translate(width/2, height/2); fill("plum"); stroke("blue"); strokeWeight(20); text(nameInput.value(), 0, 0); }

CSS styling

Notice where the button element appears in this example, and that it takes on the default CSS styling of a button. We can use CSS styling to change the position and style of the button.

Add an inline style into the head section of your index.html document:

<style>
button {
	background: lightblue;
	color: white;
	padding: 0.5em;
	border: none;
	border-radius: .5em;
	font-size: 18px;
	box-shadow: 2px 2px 0 blue;
	cursor: pointer;
}
</style>

CSS positioning

By default, buttons created by p5 are position absolute, with a top and left value set by the button.position() function. We can position it inside of the sketch, but we need to add the sketch to a new container to make that easier.

First we'll add a new div to contain the sketch and it's buttons:

<div id="sketch"></div>

Then add some styling in that old style.css we haven't touched in a while. The element width should match the width of our canvas:

#sketch {
	max-width: 720px;
	margin:0 auto;
	position:relative;
}

Now that we have the sketch container set up, set the parent of the sketch canvas and any other elements to that sketch:

var myCanvas = createCanvas(720, 360);
myCanvas.parent("container");

And we can set the CSS position of the button:

button.parent("sketch");
button.position(10, 10);

Check out more examples of HTML and CSS functionality in p5 with this tutorial: Beyond the canvas