edutecnica

Canvas

          

Esistono diversi modi per rappresentare elementi grafici all'interno di un browser, quello più semplice è l'uso del tag <img> che può incorporare nella pagina immagini di tipo bitmap in formato jpg, gif, etc.. poi è possibile far uso degli stili CSS che fanno parte del DOM (Document Object Model) che è una struttura di dati usata per rappresentare un documento HTML dal punto di vista formale.
Tuttavia, gli stili CSS sono stati progettati per garantire la formattazione del documento, non per disegnare liberamente su di esso. Per questo motivo, a partire dalla versione 5 di HTML è stato introdotto l'elemento canvas, che è un'area del documento che può supportare primitive grafiche (linee, curve etc..) in modo più adeguato.

Le immagini canvas si possono disegnare su un elemento con tag <canvas> per il quale è possibile assegnare attributi di altezza e larghezza in pixel.
Per avere accesso a questa interfaccia di disegno bisogna prima di tutto creare un contesto che è un oggetto dotato di metodi che possono intervenire sullo stesso canvas .

Esistono attualmente due modalità per contestualizzare il canvas : lo stile "2d" per le immagini bidimensionali e "webgl" per le immagini tridimensionali, attraverso l'interfaccia OpenGL anche se quest'ultima impostazione non è pienamente supportata da tutti i browser.

<canvas id="CNV" width="300" height="200" style="border:1px solid green;">

Il canvas viene sempre dichiarato all'interno di un documento HTML come un area rettangolare con le dimensioni in larghezza(width) e in altezza (height) definite in pixel.

Per quest'area rettangolare, bisogna considerare un sistema di coordinate che prevede un asse x (delle ascisse) che parte dall'angolo in alto a sinistra dell'area e prosegue in senso positivo verso destra.
Mentre l'asse y delle ordinate, è orientato a partire dall'angolo in alto a sinistra (di coordinate x=0 ed y=0) verso il basso; quindi è positivo verso il basso.

Tenendo presente queste semplici impostazioni di base è possibile introdurre un primo scritto di esempio.


in pratica si crea una variabile ctx (context) che si occupa di scrivere all'interno dell'area definita attraverso opportuni metodi.
c.moveTo(50,50);
//crea il punto di partenza alle coordinate x=50,y=50
c.lineTo(250,150);
//crea una linea fino al punto di coordinate (250,150)
c.stroke();
//attuazione dei due comandi precedenti

Come si può notare, modificando il valore delle coordinate nel codice sorgente (e poi cliccando sul pulsante di test) si modifica la linea.

Un'altra primitiva grafica molto importante è l'arco che ha la seguente sintassi

c.arc(x,y,radius,angi,angf,[senso]);

x,y : coordinate del centro
radius : raggio dell'arco
angi : angolo iniziale in radianti
angf : angolo finale in radianti
senso : 1=orario ; 0=antiorario (se il parametro è omesso si intende 0=antiorario)


Bisogna tener conto che di default JS considera positivi gli angoli che si sviluppano in senso antiorario, identificato col flag 0; se il flag è omesso si sottintende appunto antiorario=0.
Per considerare angoli che si sviluppano in senso orario bisogna specificare il flag 1. Questo comando può essere usato anche per ottenere dei cerchi: basta impostare l'angolo iniziale a 0 e quello finale a 2*Math.PI.

Si possono anche disegnare i rettangoli


Con un paio di ulteriori istruzioni è possibile dotare il rettangolo di riempimento.


E' opportuno impostare il colore di contorni e riempimenti in con coordinate RGB espresse in codice esadecimale.

Qualsiasi tracciato chiuso può essere riempito dal comando fill() una volta scelto il colore mediante la proprietà fillStyle.


Oltre alle primitive grafiche citate HTML5 e JavaScript hanno a disposizione delle trasformazioni per intervenire sul contesto.
Il metodo translate()di sintassi
ctx.translate(offset_x, offset_y);
permette di traslare l'intero canvas. Poi c'è il comando scale() di sintassi
ctx.scale(scala_x, scala_y);
per ridimensionare il contesto, tenendo conto che dei valori scala_x=1 e scala_y=1 lasciano invariare le dimensioni.
Infine c'è il metodo rotate() di sintassi
ctx.rotate(Math.PI/6);
Bisogna ricordare che tutte le trasformazioni avvengono rispetto al punto di coordinate 0,0 pixel iniziale e che tutte le trasformazioni devono essere indicate nel codice prima di aver definito il tracciato da disegnare.


Queste trasformazioni non resettano lo stato precedente del canvas, semplicemente gli disegnano sopra un nuovo tracciato; per questo motivo nell'esempio che abbiamo fatto è presente la funzione beginPath(): essa è necessaria per indicare che stiamo per eseguire un nuovo tracciato grafico indipendente dal precedente.
Inoltre all'interno delle funzioni che effettuano la trasformazione scelta, si nota l'istruzione
ctx.clearRect(0, 0, CNV.width, CNV.height);
che semplicemente cancella il contenuto dell'intera area di disegno prima di eseguirne un tracciato uguale al precedente ma dotato della trasformazione scelta.

Da queste constatazioni si deduce che muovere un elemento sul canvas richiede una certa cautela; se non si vuole cancellare l'intera area del disegno, bisogna conoscere con precisione la posizione e l'area occupata dall'elemento da muovere.


Stavolta, un rettangolo di 10×10px viene cancellato prima di essere ridisegnato nella nuova posizione.

Lo stesso principio deve essere applicato se al posto di una immagine generata via codice deve essere usata un'immagine esterna .


Nel caso si utilizzino delle immagini è sempre opportuno usare l'ascoltatore: addEventListener() per controllare che l'immagine sia stata completamente caricata prima di disegnarla.