In this workshop, we will explore p5.js as a tool to prototype with basic digital inputs. In future workshops, we will build upon the foundation to use machine learning models.
function setup() {
// windowWidth and windowHeight are variables available in p5. We will set our canvas size to take up the entire available space.
createCanvas(windowWidth, windowHeight);
}
function draw() {
background(220);
}
// When you resize the window, p5 will call this function. We will use this as an opportunity to resize the canvas to the new window width and height.
function windowResized(){
resizeCanvas(windowWidth, windowHeight)
}To prototype cursor interactions in p5, we can hide the mouse default mouse cursor and draw a cursor on the canvas at the mouse position.
Let's start by drawing a circle at the location of your cursor. The current mouse position on the canvas is given by mouseX and mouseY. In the draw function:
function draw() {
//if we draw a background every frame, we basically are clearing the canvas.
background(220);
//the circle function takes an x position, y position, radius
circle(mouseX, mouseY, 10)
}background(220) line from your draw function. What happens?To prototype new types of cursors, we most likely would want to hide the default system cursor. We can do this with the p5 function noCursor(). We can set this in the setup function of our code.
function setup() {
createCanvas(windowWidth, windowHeight);
noCursor();
}Now that we have the basic cursor setup, try modifying things to play with different forms of input. The Interactivity page on the p5 reference has a bunch of demos that you can copy+paste into your code and modify.
function draw() {
background(220);
stroke('rgb(100,50,20)');
circle(mouseX, mouseY, 10)
}function draw() {
background(220);
stroke(rgb(100,50,20));
circle(mouseX, mouseY, 10*mouseX/500);
}function setup() {
createCanvas(windowWidth, windowHeight);
noCursor();
frameRate(12);
}function draw(){
background(220);
circle(mouseX+random(-50, 50), mouseY+random(-50, 50), 10);
}function draw(){
background(220);
line(mouseX, mouseY, pmouseX, pmouseY);
}background() function. Instead of clearing everything, we can use a transparent background to slowly erase the background. If we remove the background(220) line entirely, we can create a permanent trace of the cursor.function draw(){
background('rgba(220, 220, 220, 0.2)');
circle(mouseX, mouseY, 20);
}
Here are some other examples to get inspiration from and to borrow code from:
There are two ways we can prototype buttons with p5:
In p5, we can create a html button by using the createButton() function.
function setup() {
noCanvas();
let button = createButton('click me');
}
function draw() {
}Because we don't need a canvas, we don't use the createCanvas() function, and instead specify noCanvas().
We can start to customize our button using a variety of functions provided to us from p5. This p5 reference page highlights all your options.
function setup() {
noCanvas();
let button = createButton('click me');
button.style('color', 'blue');
button.style('font-size', '18px');
}function setup() {
noCanvas();
let button = createButton('click me');
button.class('mybutton');
}and in your css file:
.mybutton{
color: blue;
font-size: 18px;
padding: 8px;
}button {
display: inline-block;
border: none;
padding: 1rem 2rem;
margin: 0;
text-decoration: none;
font-size: 1rem;
cursor: pointer;
text-align: center;
background: white;
color: black;
}mouseClicked and mouseOver. Other events you have available to you from p5:
let button;
function setup() {
noCanvas();
button = createButton('click me');
button.mouseClicked(buttonPressed);
button.mouseOver(moveButton)
}
function buttonPressed(){
button.style('background-color', 'lightblue');
}
function moveButton(){
button.position(random(0, 100), random(0, 100));
}function setup() {
noCanvas();
let button = createButton('click me');
button.position(100, 200);
}function setup() {
noCanvas();
let button = createButton('click me');
button.value('New Word')
}function setup() {
noCanvas();
let button = createButton('click me');
button.draggable();
}Here's another example of how you might mockup a button in a specific context by using a screenshot in the background:
Another approach to prototyping buttons will be to use the p5 canvas. The advantage of using this approach is that there are less constraints. However, that also means there are less convenience functions like button.mousePressed() for you to use.
function setup() {
createCanvas(windowWidth, windowHeight);
}
function draw() {
background(220);
fill('blue');
noStroke();
rect(20,20, 300, 300*2/3)
}
function windowResized(){
resizeCanvas(windowWidth, windowHeight)
}let size = 300;
function draw() {
background(220);
fill('blue');
noStroke();
rect(20,20, size, size*2/3)
}mouseClicked() function. This function will be called whenever someone clicks on the canvas. When someone clicks, let's decrease the size of our button.let size = 300;
function draw() {
background(220);
fill('blue');
noStroke();
rect(20,20, size, size*2/3)
}
function mouseClicked(){
size = size - 10;
}function mouseClicked(){
if(mouseX > 20 && mouseX < 20+size && mouseY > 20 && mouseY < 20 + size*2/3){
size = size - 10;
}
}mouseMoved() function:function mouseMoved(){
if(mouseX > 20 && mouseX < 20+size && mouseY > 20 && mouseY < 20 + size*2/3){
cursor(CROSS);
}
else{
cursor('default');
}
}Just like with the buttons, we can prototype text inputs using the built-in HTML element or we can implement text inputs by drawing directly onto the canvas.
In p5, we can create an input using the createInput() function.
let inp;
function setup() {
noCanvas();
inp = createInput();
}
function draw() {
}Once we create the function, just like with the button, we can style the input by applying styles in your p5 sketch, or by applying a class.
let inp;
function setup() {
noCanvas();
inp = createInput();
inp.class('myInput');
}
function draw() {
}
In our css, we can style the input however we want. In this case, I just increased the font size and set the width to 24ch (24 characters wide).
.myInput{
font-size: 24px;
width: 24ch;
font-family: monospace;
}changed() function or input():
let inp;
function setup() {
noCanvas();
let inp = createInput();
inp.class('myInput');
inp.input(onTyping)
//try switching 'input' to 'changed' and see what happens.
}
function draw() {
}
function onTyping(){
console.log(inp.value())
}let inp;
function setup() {
noCanvas();
let inp = createInput();
inp.class('myInput');
inp.input(onTyping)
//try switching 'input' to 'changed' and see what happens.
}
function draw() {
}
function onTyping(){
// Check if the length of text fills the whole input
if(inp.value().length > 23){
// Create a permenent record of that line
createDiv(inp.value());
// Clear the input
inp.value("");
}
}Reading: Too much Information Trust as Social Reality
Secondary Research: Research a form of sensing or new sensor and bring it to class next week for discussion.
Technology-Centered Research: Pick a specific context and prototype 2-3 different inputs (buttons, cursors, text fields, or other). Be prepared to show/demo and discuss what you did, what you learned and your opinions. No presentations
Use the workshop on prototyping cursors, buttons, and text fields, and last weeks readings to assist you in the investigation.
Be prepared to show/demo and discuss what you did, what you learned and your opinions. No presentations
What is one of your takeaways from the reading?
The reading talks about the God's Eye View asserting itself through simulations. What other perspectives can machines take? What context do they take those perspectives?
What are different dimensions by which machines "see"
Tool making as metaphors
Being "typed" and how we take on different states.
Computation projects a future that is like the past, which makes it incapable of dealing with the present which is never stable
If you were to fill out a god's eye view of society, what bodies do you imagine in it? What do you look like in this simulation? What exactly is the model of your body moving through time? What does this simulation account for, or not account for? What hidden or not sensible qualities are erased? What are you able to name easily? What are your blind spots? What should the machine eye visualize that you cannot? What is the simulation of America in which a person of color lived a full and healthy life? In which the mentally ill were cared for? In which debt slavery was abolished? In which racialized capitalism was acknowledged as real and accounted for in all aspects of society? What could technology look like if it were not built around efficiency alone, if history and narrative context were not costly aspects to be erased, but in fact essential to a complete simulation? How would our seeing, naming, and knowing change, if the practice of technology was not framed so relentlessly as constituting objective observation of phenomena, but instead as an active creator of an illusion of empirical, measurable, stable, and separate world?