p5.js — Bases et prototypage interactif
Guide concret pour démarrer avec p5.js : installation, structure minimale, dessin 2D, événements, mode 3D WebGL et export d’image.
Installation
Trois approches, de la plus simple à la plus structurée.
CDN (zéro configuration)
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/p5.min.js"></script>Ouvrir un fichier HTML dans un navigateur, écrire le sketch dans une balise
<script>, tester immédiatement. Idéal pour les prototypes rapides et les
diagrammes interactifs intégrés dans des pages existantes.
p5.js Editor (en ligne)
Se rendre sur editor.p5js.org pour expérimenter sans installer quoi que ce soit. Nécessite une connexion Internet.
Setup local (Node.js)
# Créer le projet
mkdir p5-proto && cd p5-proto
npm init -y
# Installer p5.js
npm install p5
# Servir (nécessaire pour loadFont() / loadImage() en local)
npx serve .Ouvrir http://localhost:3000 dans le navigateur.
Pitfall : charger
loadImage()ouloadFont()à partir d’un fichier HTML ouvert directement viafile://provoque une erreur CORS. Utiliser un serveur local (npx serve .oupython3 -m http.server 8080).
Structure minimale d’un sketch
Un sketch p5.js repose sur deux fonctions obligatoires : setup() et draw().
function setup() {
createCanvas(800, 600);
colorMode(HSB, 360, 100, 100, 100);
}
function draw() {
background(220, 15, 95);
fill(200, 80, 90);
noStroke();
ellipse(width / 2, height / 2, 100, 100);
}Points clés :
setup()s’exécute une seule fois au chargement. Initialiser le canvas, charger les assets, configurer les couleurs.draw()s’exécute en boucle à 60 fps par défaut. Chaque appel peint un nouveau frame.background()efface le frame précédent. Sans appel àbackground(), les formes s’empilent (effet de traînée).colorMode(HSB, 360, 100, 100, 100)utilise le mode HSB (Teinte/Saturation/ Luminosité) sur une échelle [0–360, 0–100, 0–100, 0–100].
Formes de base
function draw() {
background(220, 10, 95);
// Rectangle arrondi
fill(30, 80, 90);
rect(50, 50, 120, 80, 12);
// Cercle et ellipse
fill(200, 70, 85);
circle(250, 90, 60);
fill(140, 60, 80);
ellipse(380, 90, 100, 50);
// Ligne
stroke(20, 90, 95);
strokeWeight(3);
line(50, 200, 400, 200);
// Arc
noFill();
stroke(50, 70, 90);
arc(250, 280, 120, 120, 0, PI);
}| Fonction | Description |
|---|---|
rect(x, y, w, h, radius) | Rectangle (le 4e paramètre arrondit les coins) |
circle(x, y, d) | Cercle centré |
ellipse(x, y, w, h) | Ellipse centrée |
line(x1, y1, x2, y2) | Segment de droite |
arc(x, y, w, h, start, stop) | Arc en radians |
quad(x1, y1, x2, y2, x3, y3, x4, y4) | Quadrilatère |
triangle(x1, y1, x2, y2, x3, y3) | Triangle |
Couleurs, remplissage et contours
// Remplissage et contour
fill(200, 70, 90); // Teinte 200, Saturation 70%, Luminosité 90%
stroke(20, 80, 20); // Couleur du contour
strokeWeight(3); // Épaisseur du contour (pixels)
// Supprimer le remplissage ou le contour
noFill();
noStroke();
// Transparence (canal alpha dans HSB)
fill(200, 70, 90, 70); // alpha = 70/100 = 70% opaqueAvec colorMode(RGB) : fill(r, g, b, alpha) où chaque composante va de 0 à 255.
Pitfall : le dernier argument de
fill()est l’alpha (transparence), pas la luminosité. Dans le mode HSB (avec max=100 pour le canal alpha), écrirefill(h, s, b, a)oùava de 0 à 100.
Événements souris et clavier
let pos = { x: 0, y: 0 };
function setup() {
createCanvas(800, 600);
}
function draw() {
background(220, 10, 95);
fill(200, 80, 90);
circle(pos.x, pos.y, 40);
}
// Souris déplacée — met à jour la position
function mouseMoved() {
pos.x = mouseX;
pos.y = mouseY;
}
// Clic — affiche la position dans la console
function mousePressed() {
print('Clic en (' + mouseX + ', ' + mouseY + ')');
}
// Touche pressée
function keyPressed() {
if (key === 's' || key === 'S') {
saveCanvas('capture', 'png');
}
}| Fonction | Déclenchée quand |
|---|---|
mousePressed() | Clic de souris |
mouseReleased() | Relâchement du clic |
mouseMoved() | Souris déplacée (sans clic) |
mouseDragged() | Clic maintenu + déplacement |
mouseWheel() | Molette de la souris |
keyPressed() | Touche appuyée |
keyReleased() | Touche relâchée |
windowResized() | Fenêtre redimensionnée |
Accesseurs utiles : mouseX, mouseY (position), pmouseX, pmouseY
(position de la frame précédente), key (dernière touche pressée).
Boucles de dessin dans draw()
Les structures for, while et forEach fonctionnent normalement dans draw().
function draw() {
background(220, 10, 95);
// Grille radiale de 24 éléments
for (let i = 0; i < 24; i++) {
let angle = TWO_PI * i / 24;
let x = width / 2 + cos(angle) * 200;
let y = height / 2 + sin(angle) * 200;
fill((i * 15) % 360, 70, 90);
circle(x, y, 20 + i);
}
// Courbe sinusoïdale animée
stroke(20, 80, 95);
strokeWeight(2);
beginShape();
for (let x = 0; x < width; x += 2) {
let y = height / 2 + sin(x * 0.02 + frameCount * 0.02) * 100;
vertex(x, y);
}
endShape();
}Notes :
TWO_PI=2 * PI= 360° en radians.beginShape()/endShape()permettent de dessiner des formes multi-sommets avec un seul appel (plus performant que des appels individuels dans une boucle).
Mode 3D basique (WebGL)
p5.js passe en mode 3D en utilisant le renderer WEBGL.
function setup() {
createCanvas(800, 600, WEBGL);
}
function draw() {
background(220, 10, 95);
// Lumières
ambientLight(200, 80, 90);
directionalLight(255, 255, 255, 0, 0, -1);
// Matériau
specularMaterial(200, 80, 90);
shininess(60);
// Objet 3D
rotateY(frameCount * 0.01);
rotateX(frameCount * 0.005);
box(150);
// Caméra — tourner autour de l'objet
orbitControl();
}Pitfall : en mode WEBGL, l’origine
(0, 0)est au centre du canvas (pas en haut à gauche comme en P2D). L’axe Y pointe vers le haut.
Transforms 3D — push() et pop()
Chaque transform est cumulative. Utiliser push() / pop() pour isoler.
function draw() {
background(220, 10, 95);
ambientLight(200, 80, 90);
// Cube central fixe
specularMaterial(200, 70, 85);
box(100);
// Satellites en orbite
for (let i = 0; i < 6; i++) {
push();
rotateY(frameCount * 0.02 + i * PI / 3);
translate(200, 0, 0);
rotateX(frameCount * 0.03);
specularMaterial(140 + i * 30, 70, 85);
sphere(25);
pop();
}
orbitControl();
}| Fonction | Description |
|---|---|
translate(x, y, z) | Déplacer l’origine |
rotateX(angle) | Rotation autour de X (radians) |
rotateY(angle) | Rotation autour de Y (radians) |
rotateZ(angle) | Rotation autour de Z (radians) |
scale(sx, sy, sz) | Agrandir / réduire |
push() / pop() | Empiler / dépiler la matrice de transform |
Caméra personnalisée
camera(
eyeX, eyeY, eyeZ, // position de la caméra
centerX, centerY, centerZ, // point regardé
upX, upY, upZ // direction "haut"
);orbitControl() (mode WEBGL uniquement) permet de contrôler la caméra
avec la souris : clic gauche = rotation, clic droit = translation, molette = zoom.
Export d’image
function keyPressed() {
// S → capture PNG
if (key === 's' || key === 'S') {
saveCanvas('ma-scene', 'png');
}
}saveCanvas('nom', 'png') génère un fichier PNG de la résolution actuelle du canvas.
Pour un export programmé sans interaction utilisateur, utiliser noLoop() en
setup et appeler saveCanvas() depuis draw() au frame souhaité :
let frameTarget = 180; // sauvegarder au frame 180
function setup() {
createCanvas(1920, 1080);
noLoop(); // dessiner une seule fois jusqu'au frame cible
}
function draw() {
renderFrame();
if (frameCount === frameTarget) {
saveCanvas('rendu-final', 'png');
}
}Résumé rapide — code template
function setup() {
createCanvas(800, 600);
colorMode(HSB, 360, 100, 100, 100);
}
function draw() {
background(220, 10, 95);
// Votre code ici
}
function mousePressed() {
saveCanvas('capture', 'png');
}Liens utiles
- Documentation officielle : https://processing.github.io/p5.js/
- API de référence : https://processing.github.io/p5.js/Reference/
- Éditeur en ligne : https://editor.p5js.org
- Communauté : https://forum.processing.org/two
Un fichier HTML, deux fonctions, un canvas dans le navigateur. Pas de build step, pas de serveur, pas de configuration.