DEV Community

Cover image for Canvas js: Come disegnare sul canvas al passaggio del mouse
Roberto
Roberto

Posted on

Canvas js: Come disegnare sul canvas al passaggio del mouse

In questo articolo trasformeremo il mouse in un pennello che premuto il tasto sinistro del mouse lascierà una traccia sulla nostra tela virtuale.

INIZIALIZIAMO

Inizializiamo un elemento grande 600x400

  • HTML
<canvas id="myCanvas"></canvas>
Enter fullscreen mode Exit fullscreen mode
  • JS
let canvas = document.getElementById('myCanvas');
canvas.width = 600;
canvas.height = 400;

let ctx = canvas.getContext('2d');
Enter fullscreen mode Exit fullscreen mode

TRACCIAO LA LINEA

Creiamo una funzione che ha il compito di tracciare una linea nera spessa un 1px prendendo come argomento le coordinate iniziali x1, y1 da dove partità la linea e le coordinate finali x2, y2.

Per ulteriori informazioni su come funzionano le linee ti rimando a questo articolo

let drawLine = (x1, y1, x2, y2) => {
  ctx.beginPath();
  ctx.strokeStyle = 'black';
  ctx.lineWidth = 1;
  ctx.moveTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.stroke();
  ctx.closePath();
}
Enter fullscreen mode Exit fullscreen mode

ASCOLTATORI DI EVENTI

Per tenere monitorati le azioni del mouse, abbiamo bisogno di creare dei 'EventListener'.
L' 'EventListener' è un metodo degli elementi che tiene controllato un'azione specifica e qualora questa scattasse fa partire la funzione che gli abbiamo passato.
Questa funzione ha come argomento, un oggetto con i dati del evento, ad esempio la posizione del mouse in quel momento.

Per il nostro scopo ci servirà sapere quando si muove il mouse (evento) nel canvas (elemento da controllare) e che ci passi le coordinate x e y di dov'è.

canvas.addEventListener('mousemove', e => console.log(e.offsetX, e.offsetY)

In questo caso, il canvas è l'elemento da tenere sotto controllo e l'evento è il mousemove, che vuol dire che appena il mouse si muove nel canvas, scatta e fa partire una funzione che passa come argomento un oggetto di dati tra cui e.offsetX, e.offsetY che ci dicono dove si trova il puntatore del mouse in quel momento.

Altri due eventListener che ci serviranno sono:

  • mousedown: che si attiva se un bottone del mouse è stato premuto.
  • mouseup: si attiva appena un bottone è stato rilasciato.

Alt Text

I due eventi sono complementari prima scatta il mousedown e dopo mouseup.

Per tenere traccia che il pulsante è stato premuto creiamo un booleano che diventa vero appena il pulsante viene premuto.

canvas.addEventListener('mousedown', e => {
   x = e.offsetX;
   y = e.offsetY;
   isDrawing = true;
});

canvas.addEventListener('mousemove', e => {
  if (isDrawing === true) {
    drawLine(x, y, e.offsetX, e.offsetY);
    x = e.offsetX;
    y = e.offsetY;
  }
});

window.addEventListener('mouseup', e => {
  if (isDrawing === true) {
    isDrawing = false;
  }
Enter fullscreen mode Exit fullscreen mode
  1. 'mousedown':

    • Evento: scatta quando viene cliccato un pulsante del mouse sul canvas.
    • Azione: salva le coordinate del cursore nelle variabili x e y e fa diventare 'vero' la variabile isDrawing.
  2. 'mousemove':

    • Evento: scatta se il mouse si muove nel canvas
    • Azione: se isDrawing è vero (un bottone del mouse è stato premuto) inizio a disegnare facendo partire la funzione drawLine(), passandogli come argomenti le coordinate salvate precedentemente come punto di partenza e le coordinate di dove si trova il puntatore come punti finali. Poi salva le nuove coordinate nelle variabili x, y.
  3. 'mouseup':
    Evento: scatta appena **il bottone premuto viene rilasciato* sul elemento window. Non controlliamo più solo sul canvas ma su tutta la finstra.
    *Azione: il valore di isDrawing torna a false e anche se muovo il mouse non traccia più.

Potremmo aver finito qui, ma prima di vedere il risultato finale vorrei fare una miglioria.

SEPARARE I PULSANTI DEL MOUSE

Adesso qualsiasi pulsante del mouse teniamo premuto è indifferente.
Modifichiamo il programma in modo che il tasto destro sinistro,
mentre il tasto destro ci permetta di cambiare colore tra una gamma predefinita
.

Nell'oggetto (e) che ci viene passato nei listener mousedown e mouseup c'è la proprietà button che ci indica quale bottone del mouse è stato premuto (o rilasciato).

tasto sinistro : 0
tasto centrale (rotella): 1
tasto destro: 2

Alt Text

Modifichiamo i due listener

canvas.addEventListener('mousedown', e => {
  if( e.button === 0 ){
    x = e.offsetX;
    y = e.offsetY;
    isDrawing = true;
  }
});

window.addEventListener('mouseup', e => {
  if (isDrawing === true && e.button === 0) {
    isDrawing = false;
  }
});
Enter fullscreen mode Exit fullscreen mode

Solo se il bottone premuto/rilasciato è il sinstro (0) la variabile isDrawing verrà valorizzata.

CAMBIO COLORE

Ogni volta che premiamo il tasto destro dobbiamo fargli cambiare colore.
Iniziamo con il creare un array con i nomi dei colori che vogliamo e un'altra variabile con l'indice che punterà al colore inizializzata a 0.

colorIndex = 0;
const colors = ['red', 'blue', 'green', 'orange'];

let drawLine = (x1, y1, x2, y2) => {
  ctx.beginPath();
  ctx.strokeStyle = colors[colorIndex];
  ctx.lineWidth = 1;
  ctx.moveTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.stroke();
  ctx.closePath();
}
Enter fullscreen mode Exit fullscreen mode

Così facendo la nostra riga verrà tracciata di rosso, come il primo valore dell'array ([0]).

Aggiungiamo nel listener 'moveup', potevo aggiungerlo anche al movedown o addirittura fare un nuovo listener che scattava al 'click'.

window.addEventListener('mouseup', e => {
  ...

  if( e.button === 2 ){
    colorIndex <= colors.length ? colorIndex++ : colorIndex = 0;
  }
});
Enter fullscreen mode Exit fullscreen mode

Se il bottone rilasciato è il 2, quindi il destro e se l'indice (colorIndex) è minore o uguale alla lunghezza dell'array vai al colore successivo se no torna la primo.

CONTEXTMENU

Di default quando si preme il tasto destro del mouse appare un menù che in questo frangente noi non vogliamo.
Per toglierlo esiste un listener apposta il contextmenu che permette di gestirlo.

window.addEventListener("contextmenu", e => e.preventDefault(), false);
Enter fullscreen mode Exit fullscreen mode

Senza andare troppo per le lunghe, questo riga risolve il nostro problema.

Ecco la nostra tela dove potrete disegnare i tuoi capolavori.

CONCLUSIONE

In questo articolo abbiamo visto come funzionano gli eventListener e come si gestiscono.
Quest'ultimi sono una parte fondamentale per l'interattività nel canvas.

Se avete dei consigli, suggerimenti o critiche costruttive lasciatemi un commento qui sotto oppure contattatemi trammite i miei social (linkedin, twitter).

Top comments (0)