Canvas js: Come disegnare sul canvas al passaggio del mouse
Tags: canvas, javascript, disegnare, eventlistener
Published: 2021-03-10 08:56:49

---
title: Canvas js: Come disegnare sul canvas al passaggio del mouse
published: true
description: Disegnare sul canvas con il mouse con diversi colori
tags: #canvas #js #disegnare #eventListener
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2s3txkwnscp5vlhw5yfz.jpg
---

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 <canvas> grande 600x400

* **HTML**
``` html 
<canvas id="myCanvas"></canvas>
```

* **JS**
``` js
let canvas = document.getElementById('myCanvas');
canvas.width = 600;
canvas.height = 400;

let ctx = canvas.getContext('2d');
```

###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](https://dev.to/camizzilla/canvas-javascript-5ad9)

```js
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();
}
```
### 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jlqepx26qh0ttwi4rw5e.jpg)

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.

``` js 
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;
  }
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6701vrhi9j85p61csm55.jpg)

Modifichiamo i due listener 

``` js
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;
  }
});
```

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.

``` js
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();
}
```

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'.

``` js
window.addEventListener('mouseup', e => {
  ...
              
  if( e.button === 2 ){
    colorIndex <= colors.length ? colorIndex++ : colorIndex = 0;
  }
});
```

**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.

``` js
window.addEventListener("contextmenu", e => e.preventDefault(), false);
```

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

Ecco la nostra tela dove potrete disegnare i tuoi capolavori.

{% codepen https://codepen.io/camizzilla/pen/GRNdQqa %}

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](https://www.linkedin.com/in/robertocazzaniga), [twitter](https://twitter.com/camizzilla)).