Skip to Content
Modélisation 3Dp5.js — Bases et prototypage interactif

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 &lt;script&gt;, 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() ou loadFont() à partir d’un fichier HTML ouvert directement via file:// provoque une erreur CORS. Utiliser un serveur local (npx serve . ou python3 -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); }
FonctionDescription
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% opaque

Avec 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), écrire fill(h, s, b, a)a va 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'); } }
FonctionDé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(); }
FonctionDescription
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


Un fichier HTML, deux fonctions, un canvas dans le navigateur. Pas de build step, pas de serveur, pas de configuration.