Niveau 2

Creative Coding — Niveau 2 : Intermédiaire

Suivre ce cours — GRATUITFormation encadrée — PAYANTEn accès libre : lecture + exercices. Pour un accompagnement (atelier / masterclass), passez au format encadré.
Résumé EN (abstract): This intermediate creative coding course builds on p5.js basics to develop more sophisticated generative systems. Students learn Perlin noise fields, object-oriented particle systems, vector field flows, data-driven visuals, and generative typography. They practice clean export workflows for print and screen, and apply structured iteration (sketch journal) to develop a cohesive body of work. The capstone project is a series of three related generative works around a single concept. Outline: Perlin noise fields → Particle systems (OOP) → Vector flow fields → Data-driven art → Generative typography → Audio-reactive sketches → Clean export workflow → Series project.

Objectifs d'apprentissage

À la fin de ce cours, l'étudiant·e sera capable de :

  1. Analyser (Bloom : analyzing) les propriétés du bruit de Perlin et les différencier du random pour choisir l'outil adapté à une intention.
  2. Concevoir (creating) un système de particules avec comportements (vitesse, force, durée de vie) en programmation orientée objet.
  3. Implémenter (applying) un champ de vecteurs basé sur le bruit pour générer des flux organiques.
  4. Construire (creating) une visualisation data art à partir d'un jeu de données réel (CSV ou JSON).
  5. Générer (applying) de la typographie paramétrique et animée.
  6. Exporter (applying) des œuvres haute résolution prêtes pour l'impression et la projection.

Module 1 — Bruit de Perlin avancé (2h)

Concept

Le bruit de Perlin, inventé par Ken Perlin pour le film Tron (1982) et formalisé dans un article SIGGRAPH en 1985, produit des valeurs aléatoires continues — les valeurs voisines sont proches, créant une texture "naturelle".

Perlin, K. (1985). An Image Synthesizer. SIGGRAPH '85, pp. 287–296. https://doi.org/10.1145/325334.325247

Trois dimensions du bruit :

javascript // Cartographie d'un champ de bruit 2D let scale = 0.008; for (let x = 0; x < width; x += 4) { for (let y = 0; y < height; y += 4) { let n = noise(x * scale, y * scale); let c = map(n, 0, 1, 0, 255); fill(c); noStroke(); rect(x, y, 4, 4); } }

noiseDetail(octaves, falloff) : contrôle la finesse du bruit. Plus d'octaves = plus de détail (mais plus lent).

Lab 1.1 — Paysage de bruit

Étapes :

  1. Générer une image 600×400 en cartographiant noise(x*scale, y*scale) vers la couleur
  2. Faire varier scale entre 0.002 et 0.02 — observer l'effet sur la granularité
  3. Ajouter une dimension temporelle : noise(x*scale, y*scale, frameCount*0.005) — le paysage se transforme lentement
  4. Mapper le bruit vers une palette de couleurs (pas juste gris) : teinte HSB, altitude → couleur

Module 2 — Programmation orientée objet : la classe Particule (2h)

Concept

La programmation orientée objet (OOP) permet de regrouper données et comportements dans une classe. En creative coding, c'est la base des systèmes complexes : chaque particule, oiseau, cellule est un objet avec son propre état.

`javascript class Particule { constructor(x, y) { this.pos = createVector(x, y); this.vel = p5.Vector.random2D().mult(random(1, 3)); this.acc = createVector(0, 0); this.vie = 255; // opacité = durée de vie this.taille = random(4, 12); this.teinte = random(30, 60); }

appliquerForce(force) { this.acc.add(force); }

update() { this.vel.add(this.acc); this.vel.limit(4); // vitesse maximum this.pos.add(this.vel); this.acc.mult(0); // reset accélération this.vie -= 2; // vieillissement }

estMorte() { return this.vie <= 0; }

afficher() { colorMode(HSB, 360, 100, 100, 255); fill(this.teinte, 80, 90, this.vie); noStroke(); ellipse(this.pos.x, this.pos.y, this.taille); } } `

Tableau de particules + nettoyage : `javascript let particules = [];

function draw() { background(0, 20); // trace semi-transparente

// Ajouter 3 particules par frame for (let i = 0; i < 3; i++) { particules.push(new Particule(mouseX, mouseY)); }

// Mettre à jour et nettoyer les mortes for (let i = particules.length - 1; i >= 0; i--) { particules[i].update(); particules[i].afficher(); if (particules[i].estMorte()) particules.splice(i, 1); } } `

Lab 2.1 — Système de particules interactif

Étapes :

  1. Implémenter la classe Particule ci-dessus
  2. Ajouter une force de gravité : appliquerForce(createVector(0, 0.05))
  3. Ajouter un rebond sur les bords
  4. Faire varier la teinte selon la position (map x→teinte)
  5. Bonus : ajouter une attraction vers un point fixe (distance → force)

Module 3 — Champs de vecteurs et flux organiques (2h)

Pièce interactiveChamp de fluxOuvrir ↗

Concept

Un champ de vecteurs associe à chaque point de l'espace une direction. Les particules qui suivent le champ créent des flux organiques — rivières, vent, courant marin.

Générer le champ depuis le bruit de Perlin : javascript function directionLocale(x, y) { let scale = 0.003; let t = frameCount * 0.0006; let angle = noise(x * scale, y * scale, t) * TWO_PI * 2; return p5.Vector.fromAngle(angle); }

La particule suit le champ : javascript update() { let dir = directionLocale(this.pos.x, this.pos.y); dir.setMag(1.5); // force du courant this.appliquerForce(dir); //... reste de l'update }

Visualiser le champ (debug) : javascript function afficherChamp() { let pas = 30; for (let x = 0; x < width; x += pas) { for (let y = 0; y < height; y += pas) { let dir = directionLocale(x, y); stroke(255, 40); strokeWeight(1); let dest = createVector(x, y).add(dir.copy().setMag(15)); line(x, y, dest.x, dest.y); } } }

Lab 3.1 — Flux de particules

Étapes :

  1. Combiner la classe Particule (Module 2) avec le champ de vecteurs
  2. Partir de 500 particules distribuées aléatoirement
  3. Chaque particule suit le champ + vieillissement lent (vie = 3000 frames)
  4. Pas de background() dans draw() — laisser les traces s'accumuler
  5. Générer 3 variations (changer scale et la vitesse d'évolution temporelle du champ)

Module 4 — Data art : charger et visualiser des données (2h)

Concept

Le data art transforme des données en formes visuelles avec une intention esthétique et narrative. p5.js permet de charger facilement des fichiers CSV ou JSON.

Charger un CSV : `javascript let table;

function preload() { // preload() s'exécute avant setup() table = loadTable('data.csv', 'csv', 'header'); }

function setup() { createCanvas(800, 600); for (let i = 0; i < table.getRowCount(); i++) { let valeur = table.getNum(i, 'population'); let nom = table.getString(i, 'ville'); // visualiser... } } `

Charger un JSON : `javascript let donnees;

function preload() { donnees = loadJSON('data.json'); } `

Choix de la forme pour la donnée :

Type de donnéeFormes suggestives
QuantitéTaille, surface, hauteur
CatégorieCouleur, forme
Séquence temporellePosition x (gauche→droite)
RapportAngle, proportion
DensitéNombre de points, opacité

Lien mini-cours : Data Art : donner une forme à l'invisible — voir ce mini-cours pour un exemple complet de mapping donnée→motif.

Lab 4.1 — Visualisation d'un jeu de données réel

Étapes :

  1. Télécharger un dataset simple au format CSV (ex. données climatiques, démographiques) depuis https://data.gouv.fr ou https://opendata.ma
  2. Créer un CSV avec au moins 20 lignes et 3 colonnes
  3. Charger avec loadTable et visualiser 3 variables en parallèle (ex. x = année, y = valeur, taille = autre valeur)
  4. Ajouter labels (text()) pour les valeurs extrêmes
  5. Exporter en PNG

Mini-exercice : Refaire la même visualisation avec 2 encodages visuels différents. Lequel communique mieux l'information ? Lequel est plus poétique ?


Module 5 — Typographie générative (2h)

Concept

En creative coding, le texte n'est pas seulement information — c'est forme, rythme, matière. p5.js permet de traiter les lettres comme des objets graphiques.

Charger une police custom : `javascript let maPolice;

function preload() { maPolice = loadFont('fonts/Roboto-Regular.ttf'); }

function setup() { textFont(maPolice); textSize(120); } `

Obtenir les points d'un glyphe (tracé vectoriel) : `javascript // textBounds() : boîte englobante // font.textBounds(texte, x, y, taille) → {x, y, w, h}

// Récupérer les points du contour let points = maPolice.textBounds('A', 0, 0, 200); // Note : p5.js ne donne pas directement les contours vectoriels. // Pour des effets avancés sur les tracés, utiliser opentype.js // https://opentype.js.org — parser les courbes Bézier de chaque glyphe `

Effets sur le texte : `javascript // Texte qui tremble let offsetX = random(-2, 2); let offsetY = random(-2, 2); text('CREATIVE', width/2 + offsetX, height/2 + offsetY);

// Texte répété en dégradé for (let i = 0; i < 8; i++) { fill(30, 80, 90, map(i, 0, 8, 20, 200)); text('CODE', width/2, height/2 + i * 3); } `

Lien mini-cours : Typographie Arabe en Mouvement — explore le calligraphe comme compositeur du temps.

Lab 5.1 — Affiche typographique générative

Étapes :

  1. Choisir un mot ou une phrase courte (5–20 caractères)
  2. Afficher le texte à grande taille (120–200px)
  3. Ajouter 3 effets : variation de taille par sin(), tremblement random, décalage sur les bords
  4. Intégrer le texte dans une composition avec des formes géométriques
  5. Exporter en 2400×2400 avec pixelDensity(2)

Module 6 — Audio-réactif : visualiser le son (2h)

Concept

L'audio-réactif connecte le signal sonore à des paramètres visuels. En p5.js, la bibliothèque p5.sound fournit les outils nécessaires.

p5.sound documentation : https://p5js.org/reference/#/libraries/p5.sound

FFT — Fast Fourier Transform : décompose le signal audio en fréquences. fft.analyze() retourne un tableau de 1024 valeurs (amplitude par fréquence).

Amplitude : volume global du signal.

html <!-- Ajouter dans l'HTML (avant le sketch) : --> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/addons/p5.sound.min.js"></script>

`javascript let fft, amplitude, son;

function preload() { son = loadSound('musique.mp3'); }

function setup() { createCanvas(800, 400); fft = new p5.FFT(0.8, 1024); amplitude = new p5.Amplitude(); son.loop(); }

function draw() { background(10); let spectrum = fft.analyze(); // tableau amplitude par fréquence let vol = amplitude.getLevel(); // volume global 0–1

// Visualiser le spectre en barres colorMode(HSB, 360, 100, 100); for (let i = 0; i < spectrum.length; i += 4) { let h = map(spectrum[i], 0, 255, 0, height); let teinte = map(i, 0, spectrum.length, 0, 360); fill(teinte, 80, 90); noStroke(); rect(i (width / spectrum.length) 4, height - h, width / spectrum.length * 4, h); } } `

Entrée microphone (Live input) : `javascript let mic;

function setup() { mic = new p5.AudioIn(); mic.start(); fft.setInput(mic); } `

Lab 6.1 — Visualiseur audio

Étapes :

  1. Créer un visualiseur avec le micro comme entrée (ou un fichier MP3)
  2. Visualiser le spectre FFT + l'amplitude globale
  3. Faire que l'amplitude contrôle un paramètre non-sonore (taille des particules, vitesse du champ)
  4. Créer 2 modes visuels distincts (ex. barre / radial) switchés avec la touche espace

Module 7 — Export propre et workflow de série (2h)

Concept

Un workflow d'export professionnel garantit que les sketches sont reproductibles, haute résolution et documentés.

Checklist export : `javascript function setup() { pixelDensity(2); // 2× résolution écran createCanvas(2400, 2400); // format carré haute résolution colorMode(HSB, 360, 100, 100, 100); randomSeed(SEED); // fixer le seed noiseSeed(SEED); noLoop(); }

const SEED = 137; // changer pour chaque variation `

Nommer les exports de façon traçable : javascript function keyPressed() { if (key === 's') { saveCanvas(serie-01_seed${SEED}_${year()}${month()}${day()}, 'png'); } }

Journal de sketches (sketchbook) : tenir un document avec — pour chaque sketch : date, concept, seed, ce qui a marché/pas marché, prochaine piste. C'est le journal d'atelier du creative coder.

Lab 7.1 — Série de 3 variations

Étapes :

  1. Prendre votre sketch préféré des modules précédents
  2. Identifier 2 paramètres à varier pour créer 3 œuvres distinctes de la même "famille"
  3. Exporter chaque variation en 2400×2400 avec seed documentée
  4. Écrire 3 lignes de journal pour chaque variation : intention, résultat, suite

Module 8 — L-systèmes et structures récursives (2h)

Concept

Les L-systèmes (Lindenmayer, 1968) sont des grammaires formelles qui génèrent des structures arborescentes et fractales par réécriture. En p5.js, on implémente l'interprète de l'alphabet en commandes de dessin.

Lindenmayer, A. (1968). Mathematical models for cellular interactions in development. Journal of Theoretical Biology, 18(3), 280–315.

Turtle graphics : `javascript class Tortue { constructor() { this.x = width / 2; this.y = height; this.angle = -PI / 2; // pointe vers le haut this.stack = []; }

avancer(longueur) { let x2 = this.x + cos(this.angle) longueur; let y2 = this.y + sin(this.angle) longueur; line(this.x, this.y, x2, y2); this.x = x2; this.y = y2; }

tourner(angle) { this.angle += angle; } push() { this.stack.push({x: this.x, y: this.y, a: this.angle}); } pop() { let s = this.stack.pop(); this.x = s.x; this.y = s.y; this.angle = s.a; } }

// Interpréter une chaîne L-système function interpreter(chaine, longueur, angle) { let t = new Tortue(); for (let c of chaine) { if (c === 'F') t.avancer(longueur); else if (c === '+') t.tourner(angle); else if (c === '-') t.tourner(-angle); else if (c === '[') t.push(); else if (c === ']') t.pop(); } } `

Axiome et règle pour un arbre simple : Axiome : F Règle : F → F[+F]F[-F]F Angle : 25°

Lab 8.1 — L-système paramétrique

Étapes :

  1. Implémenter la classe Tortue et la fonction interpreter()
  2. Générer 5 itérations de l'arbre simple ci-dessus
  3. Paramétrer l'angle (slider ou variable) — observer comment l'arbre change de 10° à 45°
  4. Créer votre propre règle de réécriture (2 règles différentes, lettre de dessin + lettre de saut)
  5. Animer l'angle en sin() — l'arbre respire

Projet fil rouge — "Série de 3 œuvres sur un concept"

Brief

Créer une série cohérente de 3 œuvres génératives autour d'un concept unique — trois variations d'un même système, explorant différents paramètres ou états.

Contraintes

Livrables

  1. 3 sketches p5.js (ou 1 sketch avec paramètres de série)
  2. 3 exports PNG haute résolution avec seeds
  3. Documentation de série (2 pages) : concept de la série, règles de cohérence, 3 fiches œuvre (titre, seed, paramètres clés)
  4. Journal de 3 pages : process, ce qui a été tenté, décisions finales
  5. Présentation (8 min) : montrer la série + argumenter les choix

Rubrique d'évaluation

CritèreInsuffisant (1)Satisfaisant (2)Bon (3)Excellent (4)
Maîtrise technique< 2 systèmes utilisés, bugs2 systèmes, fonctionne3+ systèmes maîtrisés, code lisibleSystèmes combinés de façon sophistiquée
Cohérence de la série3 sketches sans lienPalette communeConcept commun + variations lisiblesDialogue fort entre les 3 œuvres
Qualité formelleVisuel non intentionnelComposition lisiblePalette, équilibre, espaceSophistication formelle, tension règle/aléatoire
DocumentationAbsenteSeeds + titresFiches œuvre + concept de sérieJournal de process + réflexion sur le système
ExportPas d'export ou basse résolutionPNG présents2400+ avec seeds3 variations + seed + nom traçable

Lectures & ressources


Niveau suivant : Creative Coding — Niveau 3Formation sur mesure pour votre école ou équipe : Prendre rendez-vous

Formation sur mesure

Workshop intensif (1–2 j) pour écoles, studios, musées — théorie condensée, labs guidés, accompagnement projet.

Prendre rendez-vous (30 min, gratuit) →