6. Interacció

6.3. Interactuant amb el ratolí

Per poder utilitzar el ratolí de manera interactiva en els nostres programes, P5 ens ofereix algunes variables del sistema que emmagatzemen paràmetres relatius al moviment i posició del ratolí i diverses funcions que s’executen en detectar certs esdeveniments relacionats amb aquest.

Posició del ratolí

Podem obtenir la posició del ratolí en el nostre canvas per mitjà de les variables mouseX i mouseY:

Figura 66. mouseX i mouseY
Font: elaboració pròpia.
A la figura 66 observem com el cercle que dibuixem segueix la posició del nostre ratolí sobre el canvas, ja que com a paràmetres de les seves coordenades x i y estem utilitzant les variables mouseX i mouseY. En haver dibuixat el background() en el setup(), aquest es dibuixarà una única vegada i podem veure com a cada frame es dibuixa un cercle fidelment en la posició del ratolí. Vegem què passa si modifiquem el frame rate del nostre sketch utilitzant el mètode frameRate() i li donem una velocitat de dos fotogrames per segon:

Figura 67. mouseX y mouseY amb un frame rate més petit
Font: elaboració pròpia.
Ara podem observar que el seguiment del ratolí és molt menys fidel. Això es deu al fet que, com que hem establert una execució a una velocitat de dos frames per segon, la posició del ratolí es registra únicament una vegada cada mig segon (dues vegades cada segon).

Podem moure també el codi que dibuixa el fons des del setup() al draw():

function draw() {
  background(100);
  ellipse(mouseX, mouseY, 50, 50);
}

D’aquesta manera, els cercles deixaran d’acumular-se en el canvas, ja que a cada frame estem pintant de nou el fons, que tapa el cercle que es va dibuixar a l’anterior frame. Podem fer un ús creatiu d’aquesta circumstància si al color de fons hi donem una mica de transparència:

function draw() {
  background(100, 40); // Gris amb transparència
  ellipse(mouseX, mouseY, 50, 50);
}
Figura 68. Deixant el rastre del ratolí
Font: elaboració pròpia.

A la figura es pot observar que el rastre dels cercles es va esvaint pel fet que el background(), que no és opac al 100 %, se superposa a cada frame i la seva opacitat s’acumula fins a ocultar del tot els cercles que es van dibuixar en els frames anteriors. Si canviem el valor de transparència del fons, podrem obtenir rastres més o menys llargs.

P5 també ens ofereix un altre parell de variables pmouseX, pmouseY que emmagatzemen la posició que tenia el ratolí en el frame anterior, la qual cosa ens pot resultar útil si volem, per exemple, dibuixar una línia contínua que segueixi el moviment del ratolí:

Figura 69. Línies contínues amb pmouseX i pmouseY
Font: elaboració pròpia.
A més de per crear «pinzells», podem donar a aquestes variables l’ús que necessitem als nostres sketches. Vegem un exemple senzill en el qual canviem el color del fons depenent de la posició del ratolí en el canvas:

function setup() {
	createCanvas(400, 400);
}

function draw() {
	if(mouseX < width * 0.5){
		background("lightblue");
	} else {
		background("lightpink");
	}
}

Si executem aquest codi i movem el ratolí pel canvas, observarem que, quan el ratolí es troba a la meitat esquerra del canvas, el color de fons és blau, mentre que si el movem a la meitat dreta, el color de fons canvia a rosa.

Clics del ratolí

A més de poder usar la posició, també podem detectar quan hem fet clic amb algun dels botons del ratolí. Per a això, P5 ens ofereix la variable booleana mouseIsPressed, que tindrà un valor true quan premem qualsevol dels botons del ratolí i false en el cas contrari. Podem utilitzar una estructura condicional per avaluar aquesta variable i canviar algun paràmetre del nostre dibuix en conseqüència. En el cas següent canviem la mida d’un cercle quan es premi algun botó del ratolí:

let size = 50;
if (mouseIsPressed == true) {
  size = 100;
}
circle(width * 0.5, height * 0.5, size);

Quan en una estructura condicional avaluem una variable booleana, podem prescindir de l’operador de comparació:

if (mouseIsPressed) {
}
// Equival a:
if (mouseIsPressed == true){
}

Podem combinar les variables de posició del ratolí amb aquesta nova variable booleana per detectar si fem clic en alguna zona del nostre canvas. Vegem un exemple en el qual canviem el color de fons només si detectem que s’ha fet clic amb el ratolí dins d’un quadrat:

Figura 70. Detectando el clic del ratón dentro de una figura
Font: elaboració pròpia.

En aquest exemple, hem encadenat diverses condicions amb operadors lògics per «delimitar» l’àrea on volem que es detecti el clic del ratolí. Per a altres casos similars, podem utilitzar també el mètode dist(), al qual li passem com a paràmetres les coordenades de dos punts i ens retorna la distància entre aquests punts:

// Punto (100, 200);
let x1 = 100;
let y1 = 200;
// Punto (200, 200);
let x2 = 200;
let y2 = 200;

let distance = dist(x1, y1, x2, y2); // Retornarà 100

El mètode dist() pot resultar útil per exemple per detectar si el ratolí està dins o no d’un cercle, fet que seria més complex de delimitar encadenant condicions:

Figura 71. Detectant la posició del ratolí amb dist()
Font: elaboració pròpia.

Diferenciant entre botons

També podem detectar amb quin botó del ratolí hem fet clic, per a la qual cosa podem usar mouseButton:

if(mouseIsPressed) {
  if(mouseButton == LEFT) {
    // Botón izquierdo
  }
  if(mouseButton == RIGHT) {
    // Botón derecho
  }
  if(mouseButton == CENTER) {
    // Botón central
  }
}

Esdeveniments del ratolí

A més de les variables mouseX, mouseY, pmouseX, pmouseY i la variable booleana mouseIsPressed, P5 també ens ofereix diverses funcions que s’executen amb diferents esdeveniments del ratolí. Podeu consultar totes aquestes funcions a la referència de P5, dins de l’apartat «Events». Vegem, per exemple, un possible ús de la funció mousePressed():

Figura 72. La funció mousePressed()
Font: elaboració pròpia.
El codi que escriguem dins de la funció mousePressed() s’executarà únicament quan pressionem algun dels botons del ratolí. En aquest cas, hem creat al principi de l’sketch una variable booleana showCircle que hem inicialitzat amb el valor false. Quan fem clic amb el ratolí, s’executarà la instrucció showCircle = !showCircle, que assigna a la variable showCircle el valor contrari al que actualment té: si és false, passarà a ser true i viceversa. D’aquesta manera, podem alternar fàcilment entre un estat i un altre i mostrar o no el cercle.