Le animazioni in
JavaScript, ma in genere qualsiasi disegno 2D, possono essere gestite tramite i
canvas.
Per iniziare occorre inserire un elemento
Html di tipo
canvas nella pagina:
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Test animazione</title>
</head>
<body>
<h1>Test animazione</h1>
<canvas id="sgart-animation" width="640" height="480" style="border:1px solid #888;"></canvas>
<script src="1-sgart-animation.js"></script>
</body>
</html>
e il link a un javascript.
Nel
JavaScript per prima cosa va preso il riferimento al
canvas ed al relativo
context, necessario per disegnare sulla sua superfice:
//recupero l'elemento html canvas tramite il suo id
const canvas = document.getElementById('sgart-animation');
//canvas.width = 640; // eventualmente posso settare le dimensioni
//canvas.height = 480;
//ricavo il contesto che serve per disegnare
const ctx = canvas.getContext("2d");
tramite il
context posso disegnare, ad esempio, un cerchio in alto a destra:
const x = 40
const y = 40;
const radius = 35;
ctx.beginPath(); // inizio a disegnare gli oggetti, necessario per poi riempirli (fill)
ctx.fillStyle = '#e00'; // imposto il colore di riempimento
ctx.arc(x,y,radius, 0, 2* Math.PI);
ctx.fill();
se voglio gestire un animazione posso usare
setTimeout:
let inc = 0; //incremento della posizione
function animationLoop() {
const x = 40 + inc;
const y = 40 + inc;
const radius = 35;
ctx.beginPath(); // inizio a disegnare gli oggetti, necessario per poi riempirli (fill)
ctx.fillStyle = '#e00'; // imposto il colore di riempimento
ctx.arc(x,y,radius, 0, 2* Math.PI);
ctx.fill();
// incremento la posizione
inc++;
//richiamo l'animazione ogni 100 ms
setTimeout(animationLoop, 10);
}
animationLoop();
Se non vedi l'animazione ricarica la pagina
funziona ma ha un problema, non viene cancellato l'oggetto nella posizione precedente e quindi lascia una scia. Per risolvere basta cancellare il canvas, prima di disegnare l'oggetto nella nuova posizione. Oppure disegnare un rettangolo per creare uno sfondo colorato:
function animationLoop() {
//se non cancello prima lascio la scia
//ctx.clearRect(0,0,canvas.width, canvas.height);
//in alternativa imposto un colore di default per lo sfondo
ctx.beginPath();
ctx.fillStyle = '#000';
ctx.rect(0,0,canvas.width, canvas.height);
ctx.fill();
const x = 40 + inc;
const y = 40 + inc;
const radius = 35;
ctx.beginPath(); // inizio a disegnare gli oggetti, necessario per poi riempirli (fill)
ctx.fillStyle = '#e00'; // imposto il colore di riempimento
ctx.arc(x,y,radius, 0, 2* Math.PI);
ctx.fill();
// incremento la posizione
inc++;
//richiamo l'animazione ogni 100 ms
setTimeout(animationLoop, 10);
}
Se non vedi l'animazione ricarica la pagina
Per ottenere un animazione
migliore che sfrutta meglio le capacità del browser e della scheda video è meglio utilizzare
requestAnimationFrame anzichè
setInterval.
L'esempio finale è questo:
//prendo il riferimento al canvas
const canvas = document.getElementById('sgart-animation');
//canvas.width = 640;
//canvas.height = 480;
//ricavo il contesto che serve per disegnare
const ctx = canvas.getContext("2d");
let inc = 0;
function animationLoop() {
//se non cancello prima lascio la scia
ctx.clearRect(0,0,canvas.width, canvas.height);
//in alternativa imposto un colore di default per lo sfondo
ctx.beginPath();
ctx.fillStyle = '#222';
ctx.rect(0,0,canvas.width, canvas.height);
ctx.fill();
//inizio l'animazione
const x =40 + inc;
const y = 40 + inc;
const radius = 35;
ctx.beginPath(); // inizio a disegnare gli oggetti, necessario per usare il fill
ctx.fillStyle = '#e00'; // imposto il colore di riempimento
ctx.arc(x,y,radius, 0, 2* Math.PI);
ctx.fill();
inc++;
//meglio usare 'requestAnimationFrame' rispetto a setTimeout
//setTimeout(animationLoop, 50);
requestAnimationFrame(animationLoop);
}
animationLoop();
Se non vedi l'animazione ricarica la pagina
I pratica
requestAnimationFrame è messa a disposizione da tutti i moderni browser. La sua funzione è quella di ridisegnare il canvas quando necessario.
La funzione viene richiamata solo una volta, per questo alla fine dell'aggiornamento del canvas, va richiesto un nuovo ridisegno invocando
requestAnimationFrame(animationLoop);.
In questo modo la funzione
animationLoop viene richiamata ogni 16 ms circa. Questo tempo può variare anche in funzione dalla frequenza di refresh dello schermo.
Rispetto a
setInterval o
setTimeout impegna molto meno la CPU e produce delle animazioni più fluide.
I
canvas posso essere usati anche per creare nuovi componenti da usare nella pagina come ad esempio
Indicatore di percentuale circolare con Canvas o
Orologio analogico in HTML 5 con Canvas oppure altre tipologie di animazioni come in
Emulatore PLC Siemens S5 (BETA)