Aller au contenu

Interactivité souris

La souris est le moyen le plus direct d’agir sur un sketch. Vous pouvez faire un cercle qui suit le pointeur, un pinceau qui dessine quand on clique, une couleur qui change à chaque clic ou un objet qu’on attrape pour le déplacer.

p5.js vous donne deux sortes d’outils. D’abord des variables, qui disent à chaque instant où se trouve la souris et si son bouton est enfoncé. Ensuite des fonctions, que p5.js appelle tout seul quand il se passe quelque chose : un clic, un relâchement, un glissement.

Jonathan Puckey, Pointer Pointer : où que soit votre pointeur, une photo le montre du doigt
Jonathan Puckey, Pointer Pointer : où que soit votre pointeur, une photo le montre du doigtpointerpointer.com

Pointer Pointer est une expérience d’interaction. Où que vous placiez votre pointeur, le site trouve une photo dans laquelle quelqu’un le montre du doigt. C’est un hommage au pointeur de souris, en train de disparaître, et une réflexion sur le Big Data (la vidéo).

function setup() {
createCanvas(400, 300);
}
function draw() {
background(240);
circle(mouseX, mouseY, 40);
}
Déplacez la souris

mouseX et mouseY sont deux variables de p5.js. Avant chaque draw(), p5.js y range la position de la souris, en pixels, depuis le coin en haut à gauche du canevas (voir les coordonnées). On les utilise comme n’importe quel nombre : ici, comme position du cercle.

Le background() au début de draw() efface l’image précédente : on ne voit qu’un cercle, celui de l’image en cours. (Les pointillés et les étiquettes sont là pour vous aider, ils ne sont pas dans le code.)

Avant que la souris ne passe sur le canevas, mouseX et mouseY valent 0 : le cercle est coupé dans le coin en haut à gauche. Dans l’éditeur, quand la souris sort du canevas, p5.js continue de la suivre : mouseX peut devenir négatif, ou plus grand que width.

mouseX et mouseY ne servent pas qu’à placer des formes. Ce sont des nombres, et on peut les mettre partout où un nombre est attendu : une taille, un gris, une épaisseur, une vitesse.

function setup() {
createCanvas(400, 250);
}
function draw() {
background(240);
fill(mouseY);
circle(200, 125, mouseX);
}
Déplacez la souris

Plus la souris va vers la droite, plus mouseX est grand, et plus le cercle est grand : son diamètre est mouseX. Tout à gauche, il vaut 0 et le cercle disparaît.

mouseY règle le gris : 0 (noir) en haut, 250 (presque blanc) en bas. Le canevas fait 250 pixels de haut, presque exactement la plage des gris, de 0 à 255. C’est un hasard bien pratique : pour une autre taille de canevas, il faudrait convertir les valeurs avec map() (voir plus bas).

Voici l’outil de dessin le plus simple qui soit. La seule différence avec le premier exemple : background() est dans setup(), et plus dans draw().

function setup() {
createCanvas(400, 300);
background(240);
}
function draw() {
circle(mouseX, mouseY, 20);
}
Déplacez la souris

Le fond n’est peint qu’une seule fois, au démarrage. Ensuite, chaque image ajoute un cercle par-dessus les précédents, sans rien effacer. (Le bouton « Effacer » n’est pas dans le code : il relance le sketch.)

Bougez vite : les cercles s’espacent. draw() dessine un cercle par image, 60 fois par seconde. Si la souris parcourt 50 pixels entre deux images, il y a un trou de 50 pixels. Pour un trait continu, on relie la position précédente (pmouseX, pmouseY) à la position actuelle avec line() : c’est l’outil de dessin de la page conditions.

Vous verrez aussi ellipse(mouseX, mouseY, 20, 20) dans d’anciens exemples : une ellipse de même largeur et hauteur, c’est un cercle.

Pour réagir au bouton de la souris, il y a deux outils, aux noms très proches. Ils ne font pas du tout la même chose :

let d1 = 20;
let d2 = 20;
function draw() {
background(240);
if (mouseIsPressed) {
d1 = d1 + 1;
}
circle(100, 150, d1);
circle(300, 150, d2);
}
function mousePressed() {
d2 = d2 + 10;
}
Cliquez, ou gardez le bouton enfoncé

Gardez le bouton enfoncé deux secondes. Le cercle de gauche grandit de 1 pixel à chaque image, tant que mouseIsPressed vaut true : 120 pixels en deux secondes. La ligne 7 reste allumée tout ce temps.

Le cercle de droite, lui, grandit de 10 pixels une seule fois par clic, que le clic soit court ou long. La ligne 14 ne s’allume qu’un instant : c’est le seul moment où p5.js exécute mousePressed(). (Le bouton « Recommencer » n’est pas dans le code.)

mouseIsPressedmousePressed()
C’est…une variable, true ou falseune fonction que vous écrivez
Où ?dans draw(), avec un ifà part, au même niveau que draw()
Pour…une action continue : dessiner, pousser, grossirune action unique : changer d’état, compter, ajouter un objet

mousePressed() fait partie d’une famille de fonctions aux noms réservés. Vous les écrivez, mais vous ne les appelez jamais vous-même : p5.js le fait au bon moment, comme pour setup() et draw().

  1. function mousePressed() {1Un nom réservé : p5.js l'appelle à chaque clic
  2. d2 = d2 + 10;2Exécuté une seule fois par clic
  3. }3Au même niveau que draw(), jamais dedans
Fonctionp5.js l’appelle…
mousePressed()quand le bouton est enfoncé
mouseReleased()quand le bouton est relâché
mouseClicked()après un clic complet : enfoncé, puis relâché
doubleClicked()après un double-clic
mouseMoved()quand la souris bouge, bouton relâché
mouseDragged()quand la souris bouge, bouton enfoncé
mouseWheel()quand on tourne la molette (ou qu’on glisse à deux doigts sur un pavé tactile)
function setup() {
createCanvas(400, 300);
background(240);
}
function draw() {
}
function mouseClicked() {
let r = random(255);
let v = random(255);
let b = random(255);
background(r, v, b);
}
Cliquez sur le canevas

draw() est vide : tout se passe dans mouseClicked(). Le fond est repeint à chaque clic, puis plus rien ne le touche jusqu’au clic suivant. La couleur reste donc affichée.

Chaque appel à random(255) donne un nouveau nombre au hasard entre 0 et 255 : un pour le rouge, un pour le vert, un pour le bleu. Le bandeau montre les valeurs du dernier clic (arrondies).

Gardez le bouton enfoncé un moment : la couleur ne change qu’au relâchement. C’est la différence entre mouseClicked() (un clic complet) et mousePressed() (le bouton qui s’enfonce).

mouseWheel() reçoit un paramètre, event, qui décrit le mouvement de la molette. event.delta est positif quand on fait défiler vers le bas, négatif vers le haut :

let d = 100;
function draw() {
background(240);
circle(200, 150, d);
}
function mouseWheel(event) {
d = d + event.delta / 10;
return false;
}

La valeur de event.delta dépend de la souris, ou du pavé tactile : souvent autour de 100 par cran de molette, d’où la division par 10. Le return false empêche le navigateur de faire défiler la page en même temps.

Sur un téléphone ou une tablette, le doigt fait office de souris : mouseX et mouseY suivent le doigt, mouseIsPressed vaut true tant qu’il touche l’écran, et mousePressed() est appelée quand il se pose. Tous les exemples de cette page fonctionnent donc aussi au doigt.

mouseX, mouseY // position de la souris
pmouseX, pmouseY // à l'image précédente
mouseIsPressed // true tant que c'est enfoncé
function mousePressed() {
// une fois, à chaque clic
}
  • mouseX et mouseY sont des nombres : position, taille, couleur, tout ce qui attend un nombre.
  • Avec background() dans draw(), l’image est effacée à chaque fois. Sans, les formes s’accumulent.
  • mouseIsPressed sert dans draw(), pour une action qui dure tant qu’on appuie.
  • mousePressed(), mouseReleased(), mouseClicked(), mouseDragged()… sont appelées par p5.js, une fois par événement. On les écrit au même niveau que draw().
  • Pour attraper une forme : un test de survol dans mousePressed(), une variable qui retient si elle est tenue, et le déplacement dans mouseDragged().