A tag canvas foi introduzida no html 5 como uma das maiores novidades, introduzindo uma área onde podemos desenhar elementos específicos, formas geométricas e imagens através de javascript substituindo em certos aspectos o uso do flash.

Então vamos ao primeiro exemplo:

<!DOCTYPE html> 
<html>
    <body>
        <canvas id="canvas" width="200" height="100" style="border:1px solid #000;"> 
            Se seu navegador não suportar HTML5 você verá esta mensagem. 
        </canvas> 
    </body>
</html>

Retângulo

Para desenhar dentro da área de canvas devemos primeiro pegar o elemento canvas e pegar o contexto 2D.

window.addEventListener('load',function(){
    var elem = document.getElementById('canvas');
    var context = elem.getContext('2d');
});

Na linha 1 adicionamos uma função para ser executada após a página ser totalmente carregada, que executará nosso código para desenhar na canvas. Na linha 2 pegamos o elemento através do id que foi definido na tag e na linha 3 para pegar o contexto 2d, você deve estar se perguntando se existe um contexto 3d, no momento não pelo menos como padrão, mas exite algumas iniciativas como o WebGL.

Para desenhar retângulos podemo sutilizar vários métodos e propriedades

  • fillRect(x , y , w , h ): desenha um retângulo preenchido com a cor atribuída para o atributo fillStyle(ex.: context.fillStyle='#0000FF';). O retângulo será desenhado na posição x e y sendo esta o canto superior esquerdo e a partir deste ponto desenha para a direita a largura(w) e para baixo a altura(h).
  • context.strokeRect(x, y, w, h): desenha um retângulo sem preenchimento e com uma borda. O tamanho e cor utilizados devem ser configurados através dos atributos strokeStyle(ex.: context.strokeStyle = '#FF0000';) e lineWith(ex.: context.lineWidth = 5;)
  • context.clearRect (x, y, w, h): limpa os pixels no retângulo especificado.
context.fillStyle='#0000FF';
context.fillRect(10 , 10 , 100, 50);
 
context.strokeStyle = '#FF0000';
context.lineWidth = 5;
context.strokeRect(10, 100 , 100, 25);
 
context.fillRect (10 , 200 , 100, 50);
context.clearRect (30, 190,  50, 30);

Veja o exemplo

Caminhos

Podemos desenhar retas no canvas para isso utilizamos os métodos moveTo(x,y) e lineTo(x,y). O método moveTo serve para mover o “lapís” para a posição inicial da reta e será traçada uma reta até a posição utilizada para chamar o método lineTo, se não foi chamado inicialmente o método moveTo será utilizado a posição da ultima chamada de lineTo.

Se você chamar somente os dois métodos não irá visualizar nada, porque as linhas só são efetivamente desenhadas no canvas quando chamado o método stroke()

context.moveTo(10 , 10);
context.lineTo(200 , 200);
context.moveTo(50 , 10);
context.lineTo(250 , 200);
 context.stroke();

Veja um exemplo

Texto

Textos podem ser adicionados a área de desenho com o método fillText(texto , x , y ). Para configurar as características do texto como tamanho, tipo da fonte, negrito/itálico é feito através da propriedade font que aceita uma string com os valores separados por espaço.

context.font = "bold 24px Time New Roman";
context.fillText("Boteco ", 100, 150);
context.fillText("Digital", 140, 180);

O texto no canvas não se comporta como o texto no CSS, no caso a propriedade textAlign que aceita os valores left, center e right alinham o texto em relação ao ponto (x,y), no caso se colocarmos o alinhamento “left” o ponto informado para desenhar o texto ficará na esquerda do texto, ou seja, o texto começará no ponto. Se o alinhamento for “right” o final do texto será o ponto informado.

context.textAlign = "right";
context.fillText("right" ,200 ,350 );

Outra propriedade diferente é a baseline que recebe os valores bottom, middle e top que irá definir se o texto será plotado abaixo do ponto informado(top), na mesma linha(middle) ou abaixo(top).

context.textBaseline = "bottom";
context.fillText("bottom" ,10 ,170 );

Veja o exemplo

Imagens

Para desenhar uma imagem no canvas utilizamos o método drawImage que pode ter 3 ,5 e 9 parâmetros.

  • drawImage(image, dx, dy): desenha na área de desenho a imagem passada por parâmetro a partir do ponto (dx , dy).
  • drawImage(image, dx, dy, dw, dh) desenha a imagem passada e escala para a largura de dw e altura de dh.
  • drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh): Pega a imagem passada por parâmetro e recorta a partir do ponto(sx,sy) até as dimensões(sw,sh) e desenha no canvas no ponto(dx,dy) e escala para as dimensões(dw,dh).

A imagem que passamos por parâmetros para o método drawImage pode ser um elemento <img>,ou podemos criar um através de um construtor new Image() e atribuir o endereço de uma imagem para o atributo src.

img = new Image();
img.src = "img/hero_sprites01.png";
 
context.drawImage( img , 30, 30);
 
context.drawImage( img , 200, 30 , 60 , 60);
 
context.drawImage( img , 0, 0 , 100 , 35 , 10, 200 , 100 , 35);

Veja o exemplo

Um exemplo de animação

var elem = null;
var context = null;
var img = Array();
         
window.addEventListener('load',function(){
    elem = document.getElementById('canvas');
    context = elem.getContext('2d');
             
    for( i = 1 ; i < 8 ; i++){
        img[i] = new Image();
        img[i].src = "img/hero_sprites0"+i+".png";
    }
 
    x = 1
 
    window.setInterval(function desenha(){
             
        context.clearRect(30,30, 200,200);
        context.drawImage( img[x] , 30, 30);
 
        x++;
        if( x > 7 ){
            x = 2;
        }
        console.log(x);
    }, 150);
});

Veja o exemplo

Da linha 9 até 12 criamos um array de imagem com cada uma das imagens que compõem a animação.

Na linha 14 é criado uma variável para controlar qual das imagens do array que esta sendo mostrado no momento.

Na linha 16 é chamado o método setInterval que recebe dois parâmetros, sendo o primeiro uma função que será executada de tempos em tempos, o intervalo de tempo entre uma chamada e outra é definido no segundo parâmetro, no nosso caso 150, ou seja, nossa animação será desenhada aproximadamente 6 vezes por segundo.

Na linha 18,já dentro da função que será repetida para desenhara animação, chamamos o método clearRect para limpar a área que estamos desenhando antes de desenhar a nova imagem. É necessário chamar este método pois a imagem de sprite que estamos utilizando tem fundo transparente.

Na linha 19 desenhamos a imagem corrente do array de imagens, na posição do canvas que queremos. Na linha 21 incrementamos x para que na próxima execução do método seja desenhada uma imagem diferente e na linha 22 testamos para saber se o array já chegou ao fim, caso tenha chegado voltamos nossa variável de contator x para o inicio.

Alguns devem estar se perguntando “ok mas eu poderia fazer a mesma coisa com um gif”, verdade, mas esse exemplo pode ser modificado para funcionar através do teclado, para o personagem correr somente quando uma tecla for pressionada através do evento de teclado onkeypress, como em um jogo por exemplo.

Mas lembrando esta é somente o básico, já existe muitas bibliotecas de animação, que tornam a animação bem mais fácil.

Bem era isso T++