A tag canvas, desenhando com Javascript
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);
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();
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 );
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);
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);
});
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++