Índice do conteúdo

  1. Passos básicos para animação
  2. Controlando uma animação
    1. Atualizações agendadas
    2. Atualizando com base na interação do usuário
      1. Um sistema solar animado
      2. Um relógio animado
      3. Uma imagem panorâmica em loop
  3. Outros exemplos
  4. Veja também

Como estamos usando JavaScript para controlar os elementos do Passos básicos para animação

Esses são os passos básicos que precisa seguir para desenhar um quadaro:

  1. Limpar o canvasA menos que as formas que irá desenhar completem o canvas (por exemplo, uma imagem de fundo), precisa limpar qualquer forma que foi desenhada anteriormente. A maneira mais fácil de fazer isso é usando o método clearRect().
  2. Salvar o estado do canvas Se estiver alterando algum ajuste (como estilo, transformações, etc) que afetem o estado do canvas e quiser garantir que o estado original seja usado a cada vez que o quadro é desenhado, precisa salvar o estado original.
  3. Desenhe as formas animadas Esse é o passo onde se faz a renderização propriamente dita do quadro.
  4. Restaure o estado do canvas Se você salvou o estado do canvas, restaure-o antes de desenhar um novo quadro.

Controlando uma animação

Formas são desenhadas no canvas usando os métodos dele diretamente ou chamando-se funções personalizadas. Em circunstâncias normais, apenas visualizamos esses resultados aparecerem no canvas quando o script termina de ser executado. Por exemplo, não é possível criar uma animação dentro de um loopfor.
Isso significa que precisamos de uma forma de executar nossos desenhos em um período de tempo. Existem duas formas de controlar uma animação dessa forma.

Atualizações agendadas

Em primeiro lugar, temos as funções window.setInterval() e window.setTimeout(), que podem ser usadas para chamar uma função especifica dentro de uma certo período de tempo.

Nota: O método window.requestAnimationFrame() é atualmente a forma recomendada de agendar animações.
setInterval(function, delay)
Inicia a execução repetida da função especificada por function a cada delay milissegundos.
setTimeout(function, delay)
Executa a função especificada por function em delay milissegundos.

Se não quiser nenhuma interação do usuário é melhor usar a função setInterval() que irá executar repetidamente o código fornecido.

Atualizando com base na interação do usuário

O segundo método que podemos usar para controlar uma animação é através da entrada do usuário. Se quisermos criar um jogo. poderíamos usar eventos do teclado ou mouse para controlar a animação. Através da configuração de EventListeners, podemos capturar qualquer interação e executar nossas próprias funções e animação.
Nos exemplos abaixo, usaremos o método window.setInterval() para controlar a animação. No final desse artigo estão alguns links para exemplos que usam window.setTimeout().

Um sistema solar animado

Esse exemplo anima um pequeno modelo de nosso sistema solar.

var sun = new Image();
var moon = new Image();
var earth = new Image();
function init(){
  sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
  moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
  earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
  setInterval(draw,100);
}
function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  ctx.globalCompositeOperation = 'destination-over';
  ctx.clearRect(0,0,300,300); // clear canvas
  ctx.fillStyle = 'rgba(0,0,0,0.4)';
  ctx.strokeStyle = 'rgba(0,153,255,0.4)';
  ctx.save();
  ctx.translate(150,150);
  // Earth
  var time = new Date();
  ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
  ctx.translate(105,0);
  ctx.fillRect(0,-12,50,24); // Shadow
  ctx.drawImage(earth,-12,-12);
  // Moon
  ctx.save();
  ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
  ctx.translate(0,28.5);
  ctx.drawImage(moon,-3.5,-3.5);
  ctx.restore();
  ctx.restore();
  ctx.beginPath();
  ctx.arc(150,150,105,0,Math.PI*2,false); // Earth orbit
  ctx.stroke();
  ctx.drawImage(sun,0,0,300,300);
}
Screenshot Live sample

Um relógio animado

Esse exemplo desenha um relógio animado, exibindo sua hora atual.

function init(){
  clock();
  setInterval(clock,1000);
}
function clock(){
  var now = new Date();
  var ctx = document.getElementById('canvas').getContext('2d');
  ctx.save();
  ctx.clearRect(0,0,150,150);
  ctx.translate(75,75);
  ctx.scale(0.4,0.4);
  ctx.rotate(-Math.PI/2);
  ctx.strokeStyle = "black";
  ctx.fillStyle = "white";
  ctx.lineWidth = 8;
  ctx.lineCap = "round";
  // Hour marks
  ctx.save();
  for (var i=0;i<12;i++){
    ctx.beginPath();
    ctx.rotate(Math.PI/6);
    ctx.moveTo(100,0);
    ctx.lineTo(120,0);
    ctx.stroke();
  }
  ctx.restore();
  // Minute marks
  ctx.save();
  ctx.lineWidth = 5;
  for (i=0;i<60;i++){
    if (i%5!=0) {
      ctx.beginPath();
      ctx.moveTo(117,0);
      ctx.lineTo(120,0);
      ctx.stroke();
    }
    ctx.rotate(Math.PI/30);
  }
  ctx.restore();
  var sec = now.getSeconds();
  var min = now.getMinutes();
  var hr  = now.getHours();
  hr = hr>=12 ? hr-12 : hr;
  ctx.fillStyle = "black";
  // write Hours
  ctx.save();
  ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
  ctx.lineWidth = 14;
  ctx.beginPath();
  ctx.moveTo(-20,0);
  ctx.lineTo(80,0);
  ctx.stroke();
  ctx.restore();
  // write Minutes
  ctx.save();
  ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
  ctx.lineWidth = 10;
  ctx.beginPath();
  ctx.moveTo(-28,0);
  ctx.lineTo(112,0);
  ctx.stroke();
  ctx.restore();
  // Write seconds
  ctx.save();
  ctx.rotate(sec * Math.PI/30);
  ctx.strokeStyle = "#D40000";
  ctx.fillStyle = "#D40000";
  ctx.lineWidth = 6;
  ctx.beginPath();
  ctx.moveTo(-30,0);
  ctx.lineTo(83,0);
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(0,0,10,0,Math.PI*2,true);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(95,0,10,0,Math.PI*2,true);
  ctx.stroke();
  ctx.fillStyle = "rgba(0,0,0,0)";
  ctx.arc(0,0,3,0,Math.PI*2,true);
  ctx.fill();
  ctx.restore();
  ctx.beginPath();
  ctx.lineWidth = 14;
  ctx.strokeStyle = '#325FA2';
  ctx.arc(0,0,142,0,Math.PI*2,true);
  ctx.stroke();
  ctx.restore();
}
Screenshot Live sample

Uma imagem panorâmica em loop

Nesse exemplo, uma imagem panorâmica é rolada da esquerda para a direita. Foi usada uma imagem do Parque Nacional Yosemetie retirada da Wikipedia, mas você pode usar qualquer imagem que seja maior que o canvas.

var img = new Image();
// User Variables - customize these to change the image being scrolled, its
// direction, and the speed.
img.src = '/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
var CanvasXSize = 800;
var CanvasYSize = 200;
var speed = 30; //lower is faster
var scale = 1.05;
var y = -4.5; //vertical offset
// Main program
var dx = 0.75;
var imgW;
var imgH;
var x = 0;
var clearX;
var clearY;
var ctx;
img.onload = function() {
    imgW = img.width*scale;
    imgH = img.height*scale;
    if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
    if (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvas
    else { clearX = CanvasXSize; }
    if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvas
    else { clearY = CanvasYSize; }
    //Get Canvas Element
    ctx = document.getElementById('canvas').getContext('2d');
    //Set Refresh Rate
    return setInterval(draw, speed);
}
function draw() {
    //Clear Canvas
    ctx.clearRect(0,0,clearX,clearY);
    //If image is <= Canvas Size
    if (imgW <= CanvasXSize) {
        //reset, start from beginning
        if (x > (CanvasXSize)) { x = 0; }
        //draw aditional image
        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
    }
    //If image is > Canvas Size
    else {
        //reset, start from beginning
        if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
        //draw aditional image
        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
    }
    //draw image
    ctx.drawImage(img,x,y,imgW,imgH);
    //amount to move
    x += dx;
}

Below is the <canvas id="canvas" width="800" height="200"></canvas>

Live sample

Outros exemplos

Gartic
Multi-player drawing game.
Canvascape
A 3D adventure game (first-person shooter).
A basic ray-caster
A good example of how to do animations using keyboard controls.
canvas adventure
Another nice example that uses keyboard controls.
An interactive Blob
Have fun with the blob.
Flying through a starfield
Fly through stars, circles, or squares.
iGrapher
An example that charts stock market data.

Veja também