# Week 2
# Wat is p5.js?
p5.js (opens new window) is een JavaScript bibliotheek gebasseerd op de doelen van Processing (opens new window) (Pyhton bibliotheek) om programmeren toegankelijk te maken voor beginners, studenten, docenten, ontwerpers, kunstenaars …
p5.js is een soort schetsboek op het web en bevat een verzameling van objecten en methoden om graphics te genereren op deze schetsboek.
p5.js kan uitgebreid worden met extra bibliotheken (opens new window) en dus ook functionaliteiten om te intrageren met: het document object model, afbeeldingen, geluid, video …
p5.js is voornamelijk een wrapper bovenop de Canvas API (opens new window).
# Setup
Maak een folder aan met een naam die een indicatie geeft aan de webapplicatie, bijv.: p5_android_character
. De folder bevat de volgende structuur:
p5_android_character
(folder)js
(folder)main.js
(file)
index.html
(file)
De HTML pagina ziet er als volgt uit:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Web Programming 1: Front-End Development | Associate Degree in Computer Programming</title>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
<script src="js/main.js"></script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
De p5.js bibliotheek wordt, in het HTML-bestand, gelinkt via het <script>
element. In het src
attribuut vermelden we het pad naar het JavaScript-bestand dat we wensen te linken. Dat kan een absoluut (lokaal) of relatief (via http
of https
) pad zijn. We kiezen in dit geval voor een absoluut pad naar een online resource. p5.js wordt o.a. gehost in een CDN (Content Delivery Network).
We linken vervolgens een lokaal (relatief pad ten opzichte van het HTML-bestand) JavaScript-bestand main.js
waarin we onze eigen code (Eng. custom code) zullen schrijven. Dit bestand bevat minstens twee ingebouwde functies uit p5.js, namelijk setup()
(dit zijn de initiële settings van onze p5.js app) en draw
(waarin we o.a. graphics zullen tekenen).
Het JavaScript-bestand bevat de volgende inhoud:
function setup() {
noLoop();
}
function draw() {
}
2
3
4
5
6
7
De setup()
(opens new window) methode wordt maar één keer aangeroepen wanneer het programma start. Het wordt voornamelijk gebruikt om omgevingseigenschappen in te stellen, zoals: schermgrootte, achtergrondkleur, éénmalig laden van media (afbeeldingen, audio, video, fonts …).
De draw()
(opens new window) methode wordt direct uitgevoerd na de setup()
methode. De draw()
methode wordt continue uitgevoerd indien er geen noLoop()
methode gedefinieerd is in de setup()
of draw()
methode. Indien noLoop()
vermeld wordt in de setup()
methode, dan zal de draw()
éénmaal uitgevoerd worden. Kortom, voor animaties verwijder je de noLoop()
methode.
# Onze eerste schets in p5.js
Na de voorgaande setup te doorlopen zullen we ons eerste p5.js schets maken. Deze schets is statisch (via de noLoop()
) methode en bevat een reeks van graphics die “laag boven laag” getekend zullen worden cfr. de lagen in Adobe Photoshop CC of Adobe Illustrator CC.
In de setup()
functie creëren we een nieuwe canvas (via de Canvas API) met de dimensie van 600 pixels breed en 600 pixels hoog. We voegen geen animatie toe door de noLoop()
methode aan te spreken. Het achtergrondkleur van de canvas stellen we in op zwart via de methode background(0)
.
function setup() {
createCanvas(400, 400);
noLoop();
background(0);
}
function draw() {
rect(40, 40, width-80, height-80);
line(40, 40, width-40, height-40);
line(width-40, 40, 40, height-40);
ellipse(40, 40, 40, 40);
ellipse(width-40, 40, 40, 40);
ellipse(width-40, height-40, 40, 40);
ellipse(40, height-40, 40, 40);
ellipse(width/2, height/2, 80, 80);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
In de draw()
methode tekenen we de vormen die we wensen te generen binnen het <canvas>
element. We tekenen eerst een rechthoek die start op positie (40, 40) met een breedte gelijke aan de breedte (width
eigenschap) van de canvas vermindert met 80 en een hoogte gelijk aan de hoogte van de canvas (height
eigenschap) vermindert met 80. We trekken twee spiegelende diagonale lijnen binnen dit vierkant. In elke hoek tekenen we een cirkel via de ellipse()
methode. Tenslotte tekenen we ook een cirkel met een bepaalde dimensie in het midden van de rechthoek.
Resultaat:

# Full width and height of the viewport
We breiden de mappenstructuur uit met een CSS-bestand waarin we opmaak kunnen coderen zodanig dat elke canvas element de volledige beschikbare breedte en hoogte gebruikt van het browservenster. De mannenstructuur ziet er nu als volgt uit:
hoofdmap
(folder)js
(folder)main.js
(file)
css
(folder)main.css
(file)
index.html
(file)
De HTML pagina ziet er als volgt uit:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Web Programming 1: Front-End Development | Associate Degree in Computer Programming</title>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
<script src="js/main.js"></script>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
De opmaak zorgt ervoor dat we de volledige breedte en hoogte in de webbrowser kunnen gebruiken voor onze toekomstige schetsboek. Als je niet de volledige breedte en hoogte nodig hebt dan verwijder je gewoon de canvas
selector.
Het CSS-bestand bevat de volgende inhoud:
html, body {
margin: 0;
padding: 0;
background: rgba(0, 0, 0, 1);
}
canvas {
display: block;
width: 100vw;
height: 100vh;
overflow: hidden;
}
2
3
4
5
6
7
8
9
10
11
12
13
Het JavaScript-bestand main.js
ziet er als volgt uit:
function setup() {
createCanvas(windowWidth, windowHeight); // canvas bevat de volledige breedte en hoogte van de viewport
background(0); // achtergrondkleur van de canvas is zwart
}
function draw() {
}
2
3
4
5
6
7
# Voorbeelden
# Enlarge and Shrinking
In dit voorbeeld maken we een bol met de volgende eigenschappen:
- gecentreerd in het center van de canvas
- de bol start met een dimensie van
[0, 0]
en groeit per frame, de dimensie wordt bijgehouden door de variabeler
- indien de bol breeder wordt dan de canvas, dan wordt de groeirichting gewijzigd (groeien wordt krimpen)
- de groeirichting wordt bepaald door de variabele
direction
- indien de bol kleiner wordt dan
0
, dan wordt de groeirichting gewijzigd (krimpen wordt groeien) - de snelheid van groeien en krimpen wordt ingesteld via de variabele
speed
De code:
/*
Variables
*/
let r = 0; // Size of the elippse
let speed = 10; // Speed of the animation for the ellipse
let direction = 1; // 1: enlarge, -1: shrink
function setup() {
createCanvas(windowWidth, windowHeight); // canvas bevat de volledige breedte en hoogte van de viewport
background(0); // achtergrondkleur van de canvas is zwart
}
function draw() {
background(0);
ellipse(width/2, height/2, r, r);
if((r + speed) > width) {
direction = -1;
} else if ((r - speed) < 0) {
direction = 1;
}
// speed += 2; // acceleration
r += speed*direction;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Rectangle Height Shrink Animated
In dit voorbeeld maken we een rechthoeken die van hoogte verminderen en opschuiven in de positieve x-richting. Defineer de variabelen:
x
de x-positie van een rechthoekw
de breedte van een rechthoekh
de hoogte van de rechthoek variabel per frame
De code:
/*
Variables
*/
let x = 0; // position of the current rectangle
let w = 20; // width of a rectangle
let h = 0;
function setup() {
createCanvas(windowWidth, windowHeight); // canvas bevat de volledige breedte en hoogte van de viewport
background(0); // achtergrondkleur van de canvas is zwart
noStroke(); // no border
h = height; // start height of the first rectangle
rectMode(CENTER);
}
function draw() {
//background(0);
if(x > width) {
// Stop generating rectangles
background(255,0,0);
} else {
fill(random(0,255), random(0,255), random(0,255));
rect(x, height/2, w, h); // draw a rectangle
x += w;
h -= w/2;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# Square Animated
In dit voorbeeld maken we een rechthoeken (waarvan de dimensie afneemt totdat de breedte of hoogte van een volgende rechthoek kleiner wordt dan 0
) met de volgende eigenschappen:
- gecentreerd in het center van de canvas
- een rechthoek start met een dimensie van
[width, height]
de volledige beschikbare breedte en hoogte van de canvas - de volgende rechthoeken (wordt per frame getekend) worden kleiner en kleiner, de dimensie wordt bijgehouden door de variabelen
rW
enrH
- indien de volgende rechthoek een breedte of hoogte heeft die kleiner is dan
0
, dan wordt de het tekenen van rechthoeken gestopt - op het einde van de animatie wordt een rode rechthoek getekend maar daarop de tekst “LOVE CODE”
De code:
/*
Variables
*/
let rW = 10;
let rH = 10;
let speed = 20;
let fontRegular;
function preload() {
fontRegular = loadFont('assets/fonts/SourceCodePro-Regular.ttf');
}
function setup() {
createCanvas(windowWidth, windowHeight); // canvas bevat de volledige breedte en hoogte van de viewport
background(0); // achtergrondkleur van de canvas is zwart
//noStroke(); // no border
rectMode(CENTER);
rW = width;
rH = height;
}
function draw() {
if(rW > 0 && rH > 0) {
rect(width/2, height/2, rW, rH);
rW -= speed;
rH -= speed;
} else {
fill(255, 0, 0, 200);
rect(width/2, height/2, width*0.8, height*0.25);
textFont(fontRegular);
textSize(height*0.1);
textAlign(CENTER);
strokeWeight(16);
fill(255);
text('LOVE CODE', width/2, height/2+(textDescent()));
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Operating System Information
Maak een bestand operating_system_info.js
aan in de reeds aangemaakt folder week-1
. In deze applicatie lijsten we informatie op van ons besturingssysteem.
Voorbeeld output:
Homefolder: /Users/drdynscript
Temp folder: /var/folders/w1/c68647g15894_84z3mygb8sr0000gn/T
Hostname: MacBook-Pro-van-Philippe.local
Platform: darwin
Release: 18.7.0
Architecture: x64
Total Memory: 8GB
Free Memory: 37.703125MB
Percent used: 99.54%
Uptime: 11722s
# Art
Maak een folder art
aan met de mappenstructuur uit p5.js introductie. Deze applicatie genereert een verzameling van rechthoeken (zonder animatie) in grijstinten en op random posities.
Resultaat:
# Bouncing circle
Maak een folder circle_bouncing
aan met de mappenstructuur uit p5.js introductie. Teken een cirkel binnen deze methode startend op een random postie. Laat deze cirkel botsen tegen alle kanten van de canvas.
Resultaat:

# Random walker
Maak een folder walker_random
aan met de mappenstructuur uit p5.js introductie. Deze applicatie simuleert een wandelaar die bij iedere nieuwe frame beweegt (t.o.v. de vorige positie), hetzij (één van de 4 toestanden):
- een aantal pixels naar boven
- een aantal pixels naar beneden
- een aantal pixels naar rechts
- een aantal pixels naar links
De wandelaar vertrekt vanuit het midden van de canvas. De richting die de wandelaar maakt is één van de vier toestanden. De verplaatsing wordt weergegeven met een verbindingslijn tussen de huidige postie en de nieuwe positie.
Resultaat:

# 50 shades
# Random colors
Maak een folder 50shades_random_colors
aan met de mappenstructuur uit p5.js introductie. Deze applicatie genereert een grid van een aantal rechthoeken. De grid is schervullend. Bij elke nieuwe frame worden de rechthoeken hertekend met een random kleur per rechthoek.
Resultaat:

# Grey
Maak een folder 50shades_grey
aan met de mappenstructuur uit p5.js introductie. Deze applicatie genereert een grid van een aantal rechthoeken. De grid is schervullend. Het tekenen wordt niet herhaald, vermeld hiervoor de functie noLoop()
in de setup()
functie. Alle rechthoeken bevatten een grijstint variërend van zwart (linksboven) tot wit (rechtsonder).
Resultaat:
# HSL colors
Maak een folder 50shades_hsl_colors
aan met de mappenstructuur uit p5.js introductie. Deze applicatie genereert een grid van een aantal rechthoeken. De grid is schervullend. Bij elke nieuwe frame worden de rechthoeken hertekend met een een nieuwe kleur op basis van HSL (opens new window) (Hue, Saturation en Lightness). De Hue ligt bij iedere frame vast op een random waarde. Dat Saturation is afhankelijk van de kolommen, de Lightness is afhankelijk van de rijen.
Resultaat:

# Repeating images
Maak een folder images_repeating
aan met de mappenstructuur uit p5.js introductie. Deze applicatie genereert een aantal instanties van dezelfde afbeelding waarvan de grootte steeds verandert (kleiner worden na iedere iteratie). De afbeelding wordt geladen via de online service https://picsum.photos. Deze service genereert afbeeldingen on the fly waarin we o.a. de dimensies en randomness kunnen opgeven, bijv.: https://picsum.photos/1920/1080?random=1
(genereet een random afbeelding met een breedte van 1920
pixels en een hoogte van 1080
pixels).
Resultaat:

# Rotating repeating images
Maak een folder images_repeating_rotating
aan met de mappenstructuur uit p5.js introductie. Deze applicatie genereert een aantal instanties van dezelfde afbeelding waarvan de grootte steeds verandert (kleiner worden na iedere iteratie en met een toenemende rotatiehoek). De afbeelding wordt geladen via de online service https://picsum.photos (laden op dezelfde manier dan de voorgaande oefening).
Resultaat:
