6. Interacción

6.3. Interactuando con el ratón

Para poder utilizar el ratón de manera interactiva en nuestros programas, P5 nos ofrece algunas variables del sistema que almacenan parámetros relativos al movimiento y posición del ratón y varias funciones que se ejecutan al detectar ciertos eventos relacionados con este.

Posición del ratón

Podemos obtener la posición del ratón en nuestro canvas por medio de las variables mouseX y mouseY:

Figura 66. mouseX y mouseY
Fuente: elaboración propia.
En la figura 66 observamos cómo el círculo que dibujamos sigue la posición de nuestro ratón sobre el canvas, ya que como parámetros de sus coordenadas x e y estamos utilizando las variables mouseX y mouseY. Al haber dibujado el background() en el setup(), este se dibujará una única vez y podemos ver cómo en cada frame se dibuja un círculo fielmente en la posición del ratón. Veamos qué ocurre si modificamos el frame rate de nuestro sketch utilizando el método frameRate() y dándole una velocidad de dos fotogramas por segundo:

Figura 67. mouseX y mouseY con un menor frame rate
Fuente: elaboración propia.
Ahora podemos observar que el seguimiento del ratón es mucho menos fiel. Esto se debe a que, como hemos establecido una ejecución a una velocidad de dos frames por segundo, la posición del ratón se registra únicamente una vez cada medio segundo (dos veces cada segundo).

Podemos también mover el código que dibuja el fondo desde el setup() al draw():

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

De esta manera, los círculos dejarán de acumularse en el canvas, ya que en cada frame estamos pintando de nuevo el fondo, que tapa el círculo que se dibujó en el anterior frame. Podemos hacer un uso creativo de esta circunstancia si al color de fondo le damos un poco de transparencia:

function draw() {
  background(100, 40); // Gris con transparencia
  ellipse(mouseX, mouseY, 50, 50);
}
Figura 68. Dejando el rastro del ratón
Fuente: elaboración propia.

En la figura se puede observar que el rastro de los círculos se va desvaneciendo debido a que el background(), que no es opaco al 100 %, se superpone en cada frame y su opacidad se acumula hasta ocultar del todo los círculos que se dibujaron en los frames anteriores. Si cambiamos el valor de transparencia del fondo, podremos obtener rastros más o menos largos.

P5 también nos ofrece otro par de variables pmouseX, pmouseY que almacenan la posición que tenía el ratón en el frame anterior, lo que nos puede resultar útil si queremos, por ejemplo, dibujar una línea continua que siga el movimiento del ratón:

Figura 69. Líneas continuas con pmouseX y pmouseY
Fuente: elaboración propia.
Además de para crear «pinceles», podemos darle a estas variables el uso que necesitemos en nuestros sketches. Veamos un ejemplo sencillo en el que cambiamos el color del fondo dependiendo de la posición del ratón en el canvas:

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

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

Si ejecutamos este código y movemos el ratón por el canvas, observaremos que cuando el ratón se encuentra en la mitad izquierda del canvas, el color de fondo es azul, mientras que si lo movemos a la mitad derecha, el color de fondo cambia a rosa.

Clics del ratón

Además de poder usar la posición, también podemos detectar cuándo hemos hecho clic con alguno de los botones del ratón. Para ello, P5 nos ofrece la variable booleana mouseIsPressed, que tendrá un valor true cuando pulsemos cualquiera de los botones del ratón y false en caso contrario. Podemos utilizar una estructura condicional para evaluar esta variable y cambiar algún parámetro de nuestro dibujo en consecuencia. En el siguiente caso cambiamos el tamaño de un círculo cuando algún botón del ratón sea pulsado:

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

Cuando en una estructura condicional evaluamos una variable booleana, podemos prescindir del operador de comparación:

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

Podemos combinar las variables de posición del ratón con esta nueva variable booleana para detectar si hacemos clic en alguna zona de nuestro canvas. Veamos un ejemplo en el que cambiamos el color de fondo solo si detectamos que se ha hecho clic con el ratón dentro de un cuadrado:

Figura 70. Detectando el clic del ratón dentro de una figura
Fuente: elaboración propia.

En este ejemplo, hemos encadenado varias condiciones con operadores lógicos para «delimitar» el área donde queremos que se detecte el clic del ratón. Para otros casos similares podemos utilizar también el método dist(), al que le pasamos como parámetros las coordenadas de dos puntos y nos retorna la distancia entre dichos puntos:

// 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); // Devolverá 100

El método dist() puede resultar útil por ejemplo para detectar si el ratón está dentro o no de un círculo, algo que sería más complejo de delimitar encadenando condiciones:

Figura 71. Detectando la posición del ratón con dist()
Fuente: elaboración propia.

Diferenciando entre botones

También podemos detectar con qué botón del ratón hemos hecho clic, para lo que podemos usar mouseButton:

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

Eventos de ratón

Además de las variables mouseX, mouseY, pmouseX, pmouseY y la variable booleana mouseIsPressed, P5 también nos ofrece varias funciones que se ejecutan con distintos eventos del ratón. Podéis consultar todas estas funciones en la referencia de P5, dentro del apartado «Events». Veamos por ejemplo un posible uso de la función mousePressed():

Figura 72. La función mousePressed()
Fuente: elaboración propia.
El código que escribamos dentro de la función mousePressed() se ejecutará únicamente cuando presionemos alguno de los botones del ratón. En este caso, hemos creado al principio del sketch una variable booleana showCircle que hemos inicializado con el valor false. Cuando hagamos clic con el ratón se ejecutará la instrucción showCircle = !showCircle, que asigna a la variable showCircle el valor contrario al que actualmente tiene: si es false, pasará a ser true y viceversa. De esta manera, podemos alternar fácilmente entre un estado y otro y mostrar o no el círculo.