Les fonctions
Vous utilisez des fonctions depuis le début : circle(), fill(), background()… Elles ont été écrites par les auteurs de p5.js. Vous pouvez aussi écrire les vôtres : nuage(), arbre(), mouton(), puis les utiliser autant de fois que vous voulez, comme si elles faisaient partie de p5.js.
Vos sketches deviennent plus courts, plus lisibles, et plus faciles à modifier : on corrige le mouton à un seul endroit, et tous les moutons changent.
On dit aussi méthode : c’est le mot employé par Processing, et par d’anciennes versions de ce cours. En JavaScript, on parle de fonction, d’où le mot function.
Les exemples de cette page sont interactifs. Dans le code, les lignes surlignées en bleu sont celles qui sont exécutées en ce moment.
Pourquoi des fonctions ?
Section intitulée « Pourquoi des fonctions ? »Imaginez un paysage dont le draw() ressemblerait à ceci :
function draw() { background(135, 206, 235); // ciel soleil(500, 80); colline(0, 300); arbre(120, 280); mouton(300, 320); mouton(420, 340);}Ce code se lit presque comme une phrase. Pourtant, soleil(), colline(), arbre() et mouton() n’existent pas dans p5.js : c’est à vous de les écrire. Chacune regroupe les quelques formes qui dessinent un élément, et on peut l’appeler plusieurs fois, à des endroits différents, comme ici les deux moutons.
Le réflexe à prendre : quand vous copiez-collez un groupe de lignes, c’est probablement qu’il manque une fonction.
Définir et appeler une fonction
Section intitulée « Définir et appeler une fonction »function nuage() {1function, puis le nom choisicircle(100, 100, 60);2Entre accolades, les instructionscircle(180, 100, 60);circle(140, 100, 80);}function draw() {background(240);nuage();3L'appel : le nom, suivi de ()}
Les lignes 1 à 5 définissent la fonction : elles expliquent à p5.js ce que veut dire nuage(), mais elles ne dessinent rien. C’est la ligne 9 qui l’appelle : c’est à ce moment-là que les trois cercles sont dessinés.
Vous reconnaissez la forme : setup() et draw() sont, elles aussi, des fonctions que vous définissez. La seule différence, c’est que vous ne les appelez jamais vous-même : p5.js le fait pour vous, une fois pour setup(), puis 60 fois par seconde pour draw().
Le détour
Section intitulée « Le détour »Que se passe-t-il quand p5.js tombe sur un appel ? Il fait un détour : il saute dans la fonction, exécute ses instructions de haut en bas, puis revient juste après l’appel et continue. Voici ce draw() au ralenti, avec en plus un sol dessiné après le nuage (en vrai, tout s’exécute en un instant, avant que l’image ne s’affiche) :
function nuage() { circle(100, 100, 60); circle(180, 100, 60); circle(140, 100, 80);}
function draw() { background(240); nuage(); rect(0, 220, width, 80);}Pendant tout le détour, la ligne 9 reste allumée : on est dans nuage(), mais p5.js n’oublie pas d’où il vient. Quand il arrive à l’accolade fermante de la ligne 5, il retourne à la ligne 9 et passe à la ligne 10. (La forme qui vient d’être dessinée est en rose pour vous aider : ce n’est pas dans le code.)
Remarquez aussi que la fonction est définie avant draw(), alors qu’elle est appelée dedans. L’ordre dans lequel on écrit les fonctions n’a pas d’importance : seul compte l’ordre des appels.
Bien placer et bien nommer
Section intitulée « Bien placer et bien nommer »Une fonction se définit au même niveau que setup() et draw() : après l’accolade fermante de l’une, jamais à l’intérieur. Dans un sketch p5.js, tout le code se trouve d’ailleurs dans des fonctions, sauf la déclaration des variables communes, tout en haut (voir plus bas).
Pour le nom :
- pas d’espace ni d’accent, et une minuscule au début. Pour plusieurs mots, une majuscule à chaque nouveau mot :
dessinerMouton(); - un nom qui dit ce que fait la fonction :
nuage()plutôt quetruc(); - pas un nom déjà pris par p5.js : une fonction à vous nommée
circle()prendrait la place de celle de p5.js.
Certains noms sont réservés à un usage précis : setup(), draw(), mousePressed(), keyPressed()… Si vous définissez une fonction avec l’un de ces noms, p5.js l’appelle tout seul au bon moment (au démarrage, à chaque image, à chaque clic, à chaque touche). Vous en avez vu un exemple avec l’interrupteur.
Les paramètres
Section intitulée « Les paramètres »Notre nuage() dessine toujours le même nuage, au même endroit. Pour pouvoir le placer où on veut, on lui donne des paramètres : des variables qui reçoivent des valeurs au moment de l’appel.
function nuage(x, y) { circle(x - 40, y, 60); circle(x + 40, y, 60); circle(x, y, 80);}
function draw() { background(240); nuage(140, 100); nuage(mouseX, mouseY);}x et y sont écrits entre les parenthèses de la définition. Au premier appel, nuage(140, 100), x vaut 140 et y vaut 100 : circle(x - 40, y, 60) devient circle(100, 100, 60). On retrouve exactement le nuage de tout à l’heure.
Au second appel, x et y reçoivent la position de la souris. C’est la même fonction, avec d’autres valeurs : le bandeau sous le canevas montre celles de chaque appel, à chaque image.
Les valeurs sont attribuées dans l’ordre : la première va dans x, la deuxième dans y. C’est pour cela que circle(x, y, d) attend toujours la position avant le diamètre : les fonctions de p5.js ont, elles aussi, des paramètres.
Une fonction qui en appelle une autre
Section intitulée « Une fonction qui en appelle une autre »Une fonction peut appeler d’autres fonctions, et on peut l’appeler dans une boucle. Voici un mouton : deux pattes, un corps qui est… un nuage, et une tête noire. Avec la fonction nuage(x, y) de l’exemple précédent :
function mouton(x, y) { line(x - 30, y, x - 30, y + 65); // pattes line(x + 30, y, x + 30, y + 65); nuage(x, y); // la laine fill(0); // noir circle(x + 60, y - 10, 30); // la tête fill(255); // retour au blanc}
function draw() { background(240); for (let x = 100; x < width; x = x + 200) { mouton(x, 100); }}La boucle fait trois tours, avec x = 100, 300 et 500. À chaque tour, mouton() est appelée, et elle appelle à son tour nuage() avec les mêmes valeurs. (L’étiquette au-dessus du mouton survolé est là pour vous aider, elle n’est pas dans le code.)
Les pattes sont dessinées avant le corps : le nuage recouvre leur partie haute, et on ne voit que le bas.
Notez la dernière ligne de mouton(). Un fill() reste actif après la fin de la fonction : sans fill(255), le corps du mouton suivant serait noir. Une bonne habitude : remettre les réglages comme on les a trouvés.
Renvoyer une valeur : return
Section intitulée « Renvoyer une valeur : return »Certaines fonctions ne dessinent rien : elles calculent une valeur et la renvoient. Vous en connaissez déjà : random(255) renvoie un nombre au hasard, hour() renvoie l’heure. Pour renvoyer une valeur, on utilise le mot return :
function milieu(a, b) { return (a + b) / 2;}
function draw() { background(240); line(50, 250, mouseX, mouseY); let x = milieu(50, mouseX); let y = milieu(250, mouseY); circle(x, y, 20);}milieu() calcule le nombre qui se trouve à mi-chemin entre deux autres. À la ligne 8, l’appel milieu(50, mouseX) est remplacé par le résultat : si la souris est en x = 310, il devient (50 + 310) / 2, c’est-à-dire 180. Ce nombre est rangé dans la variable x.
La fonction est appelée deux fois par image, avec des valeurs différentes : une fois pour la position horizontale, une fois pour la position verticale. Le cercle reste donc toujours au milieu de la ligne.
Ce schéma résume le chemin des valeurs, sur un autre exemple : les valeurs de l’appel entrent dans a et b, et la valeur de return revient à la place de l’appel, dans resultat.

Dans les anciens exemples, comme celui-ci, vous verrez var à la place de let : pour nous, c’est la même chose.
Une fonction qui renvoie une valeur n’a pas forcément de paramètres. Celle-ci renvoie le nombre de secondes écoulées depuis minuit, et print() l’affiche dans la console, sous l’éditeur :
function secondesAujourdhui() { return hour() * 3600 + minute() * 60 + second();}
function draw() { print(secondesAujourdhui());}La portée des variables
Section intitulée « La portée des variables »Une variable déclarée à l’intérieur d’une fonction n’existe que dans cette fonction. Dès que la fonction est terminée, elle disparaît. Ce code produit donc une erreur :
function setup() { createCanvas(400, 300); let x = 10;}
function draw() { x = x + 1; // erreur ! circle(x, 150, 40);}Le x de setup() n’existe plus quand draw() s’exécute. La console de l’éditeur affiche alors un message de ce genre (x n’est pas défini) :

Pour qu’une variable soit accessible partout, on la déclare tout en haut, en dehors de toute fonction :
let x = 10;
function setup() { createCanvas(400, 300);}
function draw() { background(240); x = x + 1; circle(x, 150, 40);}C’est aussi vrai pour les paramètres : le x et le y de nuage(x, y) n’existent qu’à l’intérieur de nuage(). Dans l’exemple des moutons, il y a d’ailleurs deux variables x : celle de la boucle, dans draw(), et le paramètre de mouton(). Elles portent le même nom, mais chacune vit dans sa fonction, sans se gêner.
En résumé
Section intitulée « En résumé »// définir (une seule fois)function nom(a, b) { // instructions return resultat; // facultatif}
// appeler (autant de fois qu'on veut)nom(10, 20);let r = nom(10, 20);- Une fonction regroupe des instructions sous un nom. La définir ne fait rien : il faut l’appeler.
- À chaque appel, p5.js fait un détour par la fonction, puis reprend juste après l’appel.
- Les paramètres reçoivent les valeurs de l’appel, dans l’ordre.
returnrenvoie une valeur, qui prend la place de l’appel.- Une variable déclarée dans une fonction n’existe que dans cette fonction. Pour la partager, déclarez-la tout en haut.
À vous de jouer
Section intitulée « À vous de jouer »- Ajoutez à
nuage()un troisième paramètre,taille, qui remplace le diamètre80du cercle du milieu. Dessinez trois nuages de tailles différentes. - Dans le pré, ajoutez un quatrième mouton qui suit la souris.
- Écrivez une fonction
arbre(x, y), avec un tronc (rect()) et un feuillage (circle()), puis plantez une rangée d’arbres avec une boucle. - Avec
milieu(), placez un deuxième cercle à mi-chemin entre le premier cercle et la souris.
Pour aller plus loin
Section intitulée « Pour aller plus loin »star(), une fonction de la référence
Section intitulée « star(), une fonction de la référence »
Il n’y a pas de fonction star() dans p5.js. Celle-ci vient des exemples de Processing, traduite en p5.js. Elle utilise des notions que nous n’avons pas encore vues (cos(), sin(), beginShape()), mais vous pouvez l’utiliser sans tout comprendre, comme vous utilisez circle().
Elle prend cinq paramètres. À vous de trouver à quoi ils servent : le plus simple est de changer les valeurs, une à la fois, et de regarder le résultat.
function setup() { createCanvas(640, 360);}
function draw() { background(102); star(130, 180, 5, 70, 3); star(320, 180, 80, 100, 40); star(510, 180, 30, 70, 5);}
function star(x, y, radius1, radius2, npoints) { let angle = TWO_PI / npoints; let halfAngle = angle / 2; beginShape(); for (let a = 0; a < TWO_PI; a = a + angle) { let sx = x + cos(a) * radius2; let sy = y + sin(a) * radius2; vertex(sx, sy); sx = x + cos(a + halfAngle) * radius1; sy = y + sin(a + halfAngle) * radius1; vertex(sx, sy); } endShape(CLOSE);}Dans l’original, les étoiles tournent sur elles-mêmes, avec translate() et rotate() : voir Les transformations.
- Les méthodes, sur Floss Manuals : le chapitre (pour Processing) dont s’inspirait l’ancienne version de cette page.
- Les fonctions, sur MDN
- function, dans la référence p5.js