Canvas HTML: impara a creare forme e grafiche avanzate

Disegni, animazioni e interazioni attraverso le Canvas HTML

creativecode avatar Giulio Tiseo

14 Ago, 2019

~11min.

In questo tutorial imparerai ad utilizzare i metodi di base che riguardano le canvas HTML. Assimilati i concetti descritti in questo articolo, sarai in grado di creare forme di base attraverso la programmazione e potrai approfondire gli argomenti più complessi.

Canvas HTML: impara a creare forme e grafiche avanzate
Requisiti

Anche se la Canvas è un elemento HTML, è necessario che tu conosca anche gli altri linguaggi che compongono una pagina web. In particolare è importante che tu conosca le basi del Javascript, perché attraverso questo linguaggio sarà possibile popolare le canvas con nuovi oggetti e forme.  Se invece non conosci l’HTML, ti consiglio di seguire la Guida base all’HTML che trovi su questo sito.

# Creare animazioni e grafica accattivante su un sito web: da dove cominciare?

Una decina di anni fa sarebbe stato impensabile ottenere la resa che hanno la maggior parte dei siti web che oggi sono presenti fra i featured di awwwards.

Dal punto di vista visual e dell’esperienza utente, è stato fatto un balzo in avanti sorprendente. Grazie alla costante implementazione di nuovi framework che stanno favorendo lo sviluppo di sistemi sempre più sofisticati, immersivi e super accattivanti, oggi le possibilità che ci offrono le moderne tecnologie informatiche sono pressoché infinite.

Posso assicurarti che quando si è impegnati nello sviluppo di siti web e app, lavorare ad alti livelli con la grafica è uno dei momenti più gratificanti in assoluto.

Il problema che però viene evidenziato spesso da chi è alle prime armi è quello di non sapere esattamente da dove cominciare. Un altro dei motivi che porta spesso all’abbandono di questo argomento è causato dal fatto che ci si butta a capofitto su tematiche fin troppo complicate.

In questo tutorial ti parlerò della tecnologia di base per consentirti di approcciare più facilmente al mondo del visual design e del creative coding. Lo scopo è quello di permetterti di approfondire le librerie più interessanti per la gestione di animazioni, controlli di interazione ed effetti visivi.

Da dove si comincia allora? Molto semplice, dal disegno!

# Come è possibile disegnare in una pagina web?

Così come quando accadeva da bambini, il disegno viene prima di ogni altra cosa. Se intendi progettare un sito accattivante e far sì che le cose prendano vita nelle pagine, non puoi pensare di farlo senza aver prima “imparato a disegnare”.

Attenzione, per imparare a disegnare non intendo dire che tu debba essere necessariamente un illustratore o un’illustratrice. Quello che intendo sottolineare è l’importanza dell’approccio che hanno i bambini con il disegno (seppure inconsciamente), quindi capire come realizzare le forme di base e tentare man mano di ottenere risultati sempre più complessi.

Per cominciare, ciò di cui hai bisogno è un foglio di carta dove poter disegnare. Prima che tu vada alla ricerca del vecchio scatolone impolverato dove conservi gelosamente matite Faber-Castell e colori Giotto, voglio rassicurarti sul fatto che per tua fortuna, almeno i fogli di carta, ti vengono gentilmente forniti dal linguaggio HTML.

La specifica HTML5 mette a nostra disposizione una tecnologia piuttosto avanzata che prende il nome di Canvas e che appunto ci consente di disegnare nel browser. Avrai quindi la possibilità, grazie alle canvas html, di realizzare elementi grafici che vanno dalle semplici forme di base fino a veri e propri videogames.

Capire come funziona la canvas html ti spalancherà le porte al mondo delle animazioni per il web, quindi mettiti comodo, apri il tuo editor di testo e prepara una nuova pagina html.

# Predisporre la Canvas HTML

Come ti dicevo nel paragrafo precedente, la prima cosa che devi fare è procurarti un foglio di carta. Puoi ottenerlo direttamente nella tua pagina web creando una nuova canvas HTML in questo modo:

<canvas></canvas>

L’elemento canvas non è ancora pronto fin quando non decidi le dimensioni che dovrà avere. Per dichiarare le dimensioni della canvas HTML, ti basterà applicare gli attributi width e height, così come si fa solitamente per le immagini HTML.

<canvas height="200" width="200"></canvas>

La canvas adesso è stata creata, anche se non vedi nulla. Puoi provare a verificarne l’esistenza attraverso l’ispeziona elemento della developer tools, oppure associando al documento HTML un foglio di stile CSS, così da poter applicare un bordo che metta in evidenza il perimetro della canvas.

canvas {
  border: 1px solid purple;
}

Come vedi, hai appena ottenuto un foglio bianco da disegno, evidenziato da un bordo viola.

Adesso che la canvas è pronta, puoi iniziare a disegnare le prime forme di base. Normalmente avresti bisogno di una matita, ma nel caso delle canvas HTML la matita che ti occorre ha un nome: Javascript.

In pratica con il Javascript potrai creare nuove forme, programmarle e renderle interattive. Il javascript è il tuo strumento da lavoro, quello col quale dovrai sporcarti le mani!

A tal proposito può essere utile associare alla canvas HTML un attributo id in modo da poterla controllare in Javascript.

<canvas id="canvas" "height="200" width="200"></canvas>

Adesso, collega il documento HTML a un nuovo file Javascript. All’interno di script.js, associa la canvas a una nuova variabile puntando al suo id e definisci il “contesto” in cui il tuo disegno deve essere realizzato col metodo getContext().

Cos’è il metodo getContext()? In poche parole è la funzione che ci permette di creare l’ambiente adatto al disegno che intendiamo realizzare.

Si tratta di un disegno che può andar bene in un foglio bidimensionale o deve trovarsi in un ambiente tridimensionale?

In questo tutorial ti parlerò esclusivamente del contesto bidimensionale, perciò puoi definire il contesto della canvas HTML in questo modo:

var ctx = document.getElementById('canvas').getContext('2d');

# Disegnare in una canvas HTML bidimensionale

Per realizzare delle forme all’interno della canvas HTML, il contesto che abbiamo scelto nella fase preliminare ti permette di accedere ad una API ricca di metodi e funzioni che puoi sfruttare. Ad esempio puoi provare a creare un quadrato ricorrendo al metodo fillRect() in questo modo:

ctx.fillRect(0, 0, 50, 50);

I parametri che trovi all’interno del metodo fillRect() vanno letti come segue:

“Disegna un quadrilatero le cui coordinate dell’angolo posto in alto a sinistra sono, rispetto alla canvas, x: 0 e y: 0*. Il quadrilatero inoltre deve avere una larghezza e un’altezza di 50px.”

Quadrato in una canvas HTML
Quadrato disegnato in una canvas HTML con coordinate 0,0 e dimensione 50px;
ctx.filleRect([coordX], [coordY], [width], [height])

*ATTENZIONE: quando si lavora in grafica, il piano cartesiano è traslato in modo tale che l’origine degli assi corrisponda al punto più in alto a sinistra. Ne consegue che i valori positivi dell’asse delle ordinate (y) si estendano verso il basso, mentre quelli dell’asse delle ascisse (x) verso destra.

Coordinate in Canvas HTML
L’origine del piano cartesiano corrisponde al punto in alto a sinistra, mentre gli assi si estendono positivamente verso destra (x) e verso il basso (y)

Per creare un rettangolo che copra dinamicamente tutta l’area della pagina puoi scrivere:

ctx.fillRect(0, 0, canvas.width, canvas.height);

Qualora le dimensioni del rettangolo dovessero superare quelle della canvas, verrà tagliato e non sarà visibile oltre i limiti imposti dalla canvas stessa.

# Colorare gli oggetti di una canvas HTML

Per colorare gli oggetti che crei all’interno di una canvas HTML puoi utilizzare il metodo fillStyle, che aggiungerà un colore di riempimento diverso a tutti gli oggetti che dichiarerai da quella riga di codice in poi.

var ctx= document.getElementById('canvas').getContext('2d');
ctx.fillStyle = '#EF053D';
var rect = ctx.fillRect(0, 0, 50, 50);

Tutti le grafiche che realizzerai dopo la dichiarazione canvas.fillStyle verranno colorate con #EF053D. Ricorda di dichiarare il colore sempre come stringa, anche nel caso di colori rgb() o rgba()

ctx.fillStyle = 'rgb(239, 5, 61)';

Se intendi creare una nuova forma e vuoi che abbia un colore diverso ti basterà sovrascrivere il valore di fillStyle dell’oggetto canvas, con un altro colore.

ctx.fillStyle = '#EF053D';
var rect = ctx.fillRect(0, 0, 50, 50);
ctx.fillStyle = '#008f95';
var second_rect = ctx.fillRect(60, 0, 50, 50);
Due quadrati colorati in modo diverso con FillStyle
Per colorare due quadrati con colori diversi basta sovrascrivere il valore di fillStyle nella canvas HTML

Prova a spostare a tuo piacimento i quadrati nella canvas in modo da acquisire dimestichezza. Se non hai ancora ben chiaro il modo corretto per spostare gli oggetti nella canvas, osserva l’esempio qui sotto:

var ctx = document.getElementById('canvas').getContext('2d');
ctx.fillStyle = 'rgba(239,6,61,0.8)';
var rect = ctx.fillRect(75, 75, 50, 50);
ctx.fillStyle = 'rgba(0, 142,149,0.5)';
var second_rect = ctx.fillRect(50, 55, 50, 50);
Due quadrati che si sovrappongono in una canvas HTML

# Disegnare circonferenze in una canvas HTML

La specifica HTML5 non fornisce, come per il rettangolo, un metodo già pronto per realizzare circonferenze. Per farlo, occorre ingegnarsi un po’ con il metodo arc() e fare quindi in modo di creare una curva che ruoti di 360 gradi. Ops, ho detto “360 gradi“! Volevo dire 2PI (pi greco, ricordi? Le scuole superiori… la trigonometria…).

Quando si è alle prese con il metodo arc(), occorre farsi due calcoli prima di riuscire creare una circonferenza. Il dover ragionare in radianti e non in gradi può essere frustrante all’inizio, ma sta tranquillo… non è niente di troppo complicato…

 

Prima di entrare nel vivo del metodo arc() però, hai bisogno di inizializzare nella canvas un blocco di codice all’interno del quale potrai definire la circonferenza.

Essendo arc() un metodo piuttosto versatile e meno schematico di fillRect(), potrai creare tantissime forme. Proprio per questo motivo il codice che definisce i parametri di tale forma, vanno racchiusi all’interno di un blocco di dichiarazioni delimitate dai metodi beginPath() e closePath().

canvas.beginPath()
// Qui creerai la circonferenza
canvas.closePath()

Per creare una circonferenza col metodo arc() devi prendere in considerazione una dichiarazione strutturata in questo modo:

ctx.arc([coordCentroX], [coordCentroY], [raggio], [angoloDiPartenza], [angoloDiChiusura])

Analizziamo ciascun parametro per capire esattamente in cosa consiste questa dichiarazione:

  1. Coordinata X del punto centrale della curva;
  2. Coordinata Y del punto centrale della curva;
  3. Raggio di apertura della curva rispetto al punto centrale;
  4. Angolo di partenza della curva dichiarato in radianti;
  5. Angolo di chiusura della curva dichiarato in radianti;

Considerata una canvas HTML di dimensioni 200×200, se volessimo creare una circonferenza posta a centro canvas, inscritta al suo interno, dovremo scrivere:

ctx.arc(100, 100, 100, [angoloDiPartenza], [angoloDiChiusura])

A questo punto, prima di definire l’angolo di partenza e l’angolo di chiusura della circonferenza devi un attimo rispolverare qualche piccola nozione trigonometrica di base.

Considerato che l’angolo piatto (180 gradi) corrisponde a PI, ne consegue che l’angolo giro (360 gradi) sia uguale a 2 * PI (ovvero: 2 * 180 gradi).

Perciò, se l’angolo di partenza della circonferenza è 0, quello di chiusura sarà 360 gradi, che in radianti corrisponde appunto a 2 * PI.

Javascript mette a disposizione il valore della costante PI nel metodo Math, quindi puoi scrivere:

ctx.arc(100, 100, 100, 0, 2 * Math.PI)

In questo modo hai creato la circonferenza, anche se non vedi alcun cambiamento nella canvas. Questo accade perché, essendo semplicemente una curva, non è così scontato che debba avere un colore di riempimento o una traccia di contorno. Per aggiungere queste caratteristiche al path appena creato ricorriamo ai metodi fill() per il riempimento e stroke() per la traccia.

ctx.beginPath();
ctx.fillStyle = 'rgba(0, 142,149, 1)';
ctx.arc(100, 100, 100, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
ctx.closePath();
Circonferenza in canvas HTML
Per ottenere una circonferenza in una canvas basta scrivere [context].arc([centroX], [centroY], [raggio], 0, 2 * PI)

Ottimo, la circonferenza inscritta alla canvas è stata creata e non è per niente male. Adesso proviamo a fare un po’ di pratica con il metodo arc() per prendere confidenza con i radianti.

Abbiamo detto che l’angolo piatto corrisponde a PI, mentre l’angolo giro corrisponde a 2 * PI. Riesci a capire come ottenere nella canvas un risultato simile a questo?

Creare mezza circonferenza con senso orario in canvas HTML

Osservando la canvas dovresti aver capito che ad essere variato prima di tutto è il punto di partenza della circonferenza. Se non capisci di cosa sto parlando, osserva il grafico qui sotto che ti mostra la divisione dell’angolo giro in quattro parti uguali.

Suddivisione della circonferenza in quattro parti uguali
0 deg = 0 * PI | 90 deg = 1.5* PI | 180 deg = 1 * PI | 270 deg = 0.5 * PI

Ne consegue che per ottenere la mezza circonferenza vista nell’esempio precedente, il punto di partenza corrisponderà a 1.5 * PI, mentre la chiusura a 0.5 * PI.

ctx.arc(100, 100, 100, 1.5 * Math.PI, 0.5 * Math.PI);

In questo momento sei legittimato a protestare e dirmi: “perché il punto di partenza è 90 gradi e non 270?!” Perché non ti ho ancora parlato del sesto parametro opzionale di arc() ovvero quello che ti permette di specificare il senso di rotazione.

ctx.arc([coordCentroX], [coordCentroY], [raggio], [angoloDiPartenza], [angoloDiChiusura], [opz: sensoDiRotazione])

Questo parametro opzionale è un valore booleano (true/false): con false (che è il valore impostato di default) applichiamo ad arc() una rotazione oraria, mentre con true una rotazione antioraria. Scrivendo quindi…

ctx.beginPath();
ctx.fillStyle = 'rgba(0, 142,149, 1)';
ctx.arc(100, 100, 100, 1.5 * Math.PI, 0.5 * Math.PI, true);
ctx.fill();
ctx.stroke();
ctx.closePath();

…otterrai un oggetto speculare all’esempio visto in precendenza perché ho semplicemente invertito il senso di rotazione da orario ad antiorario.

Creare circonferenze multiple: creiamo una Sfera Poké!

Così come abbiamo visto per fillRect() è possibile realizzare diverse circonferenze nella stessa canvas, ma devi fare attenzione a una cosa! Per creare diverse forme con il metodo arc() devi ricordarti di chiudere un path e aprirne uno nuovo per ogni oggetto che creerai.

var ctx = document.getElementById('canvas').getContext('2d');

ctx.beginPath();
ctx.fillStyle = '#EF053D';
ctx.arc(100, 100, 100, 0, 1 * Math.PI, true);
ctx.fill();
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = 'rgba(24,30,40,0.1)';
ctx.arc(100, 100, 100, 0, 1 * Math.PI);
ctx.fill();
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = 'rgba(24,30,40,0.05)';
ctx.arc(100, 100, 100, 1.5 * Math.PI, 0.5 * Math.PI);
ctx.fill();
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = '#FCFCFC';
ctx.arc(100, 100, 32, 0, 2 * Math.PI, true);
ctx.fill();
ctx.stroke();
ctx.closePath();

ctx.beginPath();
ctx.arc(100, 100, 25, 0, 2 * Math.PI, true);
ctx.stroke();
ctx.closePath();

…risultato:

Prototipo di sfera poke realizzata con canvas HTML
Prototipo di una sfera poké realizzata in una canvas HTML

Già che ci siamo, proviamo a migliorare questo esempio con i metodi lineWidth, strokeStyle() e moveTo() / lineTo()

var ctx = document.getElementById('canvas').getContext('2d');

ctx.beginPath();
ctx.fillStyle = '#EF053D';
ctx.arc(100, 100, 100, 0, 1 * Math.PI, true);
ctx.fill();
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = 'rgba(24,30,40,0.1)';
ctx.arc(100, 100, 100, 0, 1 * Math.PI);
ctx.fill();
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = 'rgba(24,30,40,0.05)';
ctx.arc(100, 100, 100, 1.5 * Math.PI, 0.5 * Math.PI);
ctx.fill();
ctx.closePath();

ctx.beginPath();
ctx.moveTo(0, 100);
ctx.lineTo(200, 100);
ctx.lineWidth = 8;
ctx.stroke();
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = '#FCFCFC';
ctx.arc(100, 100, 32, 0, 2 * Math.PI, true);
ctx.fill();
ctx.lineWidth = 8;
ctx.stroke();
ctx.closePath();

ctx.beginPath();
ctx.fillStyle = '#fff';
ctx.arc(100, 100, 22, 0, 2 * Math.PI, true);
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = 'lightgray';
ctx.stroke();
ctx.closePath();

Adesso va molto meglio!

Sfera Poké in canvas HTML

Vediamo nel dettaglio le modifiche apportate alla canvas:

  • Creazione di una linea attraverso i metodi moveTo() e lineTo(): in moveTo() vai ad impostare le coordinate del punto di partenza della linea, mentre con lineTo() dichiari il punto finale.
  • Aumentare lo spessore del bordo con lineWidth: accetta come valore numeri interi che indicano la quantità di pixel da usare per lo spessore della traccia.
  • Cambiare il colore della traccia con strokeStyle: che accetta qualsiasi colore in formato HEX, rgb, rgba o i classici color preset dell’HTML.

Come vedi, con un po’ di pratica è stato possibile creare qualcosa di più interessante di un semplice quadrato colorato.

Ovviamente questo è solo l’inizio! La canvas HTML offre un’infinità di altre possibilità che non mancherò di mostrarti nei prossimi tutorial. Nel frattempo, puoi sbizzarrirti e iniziare a sperimentare con questa straordinaria API approfondendo l’argomento anche sull’eccellente documentazione stilata da mozilla.

Buon creative coding e alla prossima!

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *