Introdução ao HTML5 Canvas API
Introdução ao HTML5 Canvas API
Com a chegada do HTML5, ganhamos também a possibilidade de utilizar o Canvas API, que permite-nos, através do elemento <canvas>, desenhar elementos gráficos na tela do navegador, via Javascript.
O elemento <canvas> é uma TAG HTML similar a outras como <a>, <div>, <table>, etc com a excessão de que o conteúdo desta TAG é renderizado com o JavaScript.
Para utililizá-lo, é necessário colocarmos a TAG <canvas> em algum lugar dentro do código HTML, criarmos uma função em JavaScript para acessar a TAG <canvas> (via DOM) assim que a página for carregada, e utilizar a Canvas API para criar os seus desenhos na tela.
Segue abaixo um exemplo básico sobre como utilizá-lo:
<!DOCTYPE HTML>
<html>
<head>
<script>
// Função para acessar o elemento Canvas do HTML, via DOM
window.onload = function(){
// Definição da variável para acessar o elemento
var canvas = document.getElementById("TreinaWebCanvas");
// Definição do contexto 2D ou 3D
var context = canvas.getContext("2d");
// Aqui vai o código para criação dos elementos gráficos
context.fillRect(30,20,120,80);
};
</script>
</head>
<body>
<canvas id="TreinaWebCanvas" width="500" height="500"></canvas>
</body>
</html>
Como visto acima, antes começar a utilizar o Canvas, é necessário acessar o elemento, via DOM, e definir o contexto para o desenho.
Neste caso, utilizamos o contexto 2D, mas também seria possível definir o contexto como 3D (renderizado com WebGL). No entanto, não trataremos sobre o assunto neste artigo.
Com isso, o código acima serve de template base para todos os seus projetos em HTML5 Canvas. Você também precisa definir a altura e largura do seu “contexto de trabalho”, assim como define em qualquer outra TAG do HTML.
Vamos agora utilizar o Canvas para criar alguns desenhos simples.
Contexto bidimensional
O contexto bidimensional (baseado em x e y) trabalha sob um sistema de eixos cartesianos com a coordenada X (canto superior da tela) crescendo da esquerda para a direita e com a coordenada Y do canto superior ao inferior (de cima para baixo), conforme imagem abaixo:

Primeiro exemplo
Como o primeiro exemplo deste artigo é um template padrão para todos os projetos em HTML5 canvas, vamos apenas adicionar a linha abaixo, na parte dos comentários.
// Aqui vai o código para criação dos elementos gráficos
context.fillRect(30,20,120,80);
Como resultado, teremos um retângulo:

Os parâmetros passados para fillRect() são: coordenadas x e y (pontos iniciais), largura e altura do objeto. Ou seja:
context.fillRect(x, y, w, h);
Outro exemplo:
Vamos definir algumas outras propriedades como a cor, espessura, cor da borda, etc do objeto a ser desenhado.
Para isso, adicione as linhas abaixo:
// Aqui vai o código para criação dos elementos gráficos
context.fillStyle = '#4E7AA1'; // Definição da cor
context.fillRect(30, 50, 75, 150); // Cria retângulo sólido
context.strokeStyle = '#234666'; // Cor da borda
context.lineWidth = 5; // Espessura da linha
context.strokeRect(9, 19, 55, 100); // Cria apenas bordas do retângulo
O resultado no browser, será:

Mais um exemplo:
Vamos agora criar uma função simples, porém um pouco mais complexa do que o feito até agora. Iremos criar uma grid, algo que pode ser útil durante o desenvolvimento de seus projetos, para comparação visual dos tamanhos e posições dos objetos.
Para isso, utilizaremos a função abaixo:
function displayGrid(context) {
var gridSize = 15, width = 500;
for (var ypos = 0; ypos < width; ypos += gridSize) {
context.moveTo(0, ypos);
context.lineTo(width, ypos);
}
for (var xpos = 0; xpos < width; xpos += gridSize) {
context.moveTo(xpos, 0);
context.lineTo(xpos, width);
}
context.strokeStyle = "#000";
context.lineWidth = 1;
context.stroke();
}
E então o seguinte código na execução:
// Aqui vai o código para criação dos elementos gráficos
displayGrid(context);
Veja o resultado em execução:

Veja também como ficou o código do exemplo completo:
<!DOCTYPE HTML>
<html>
<head>
<script>
function displayGrid(context) {
var gridSize = 15, width = 900;
for (var ypos = 0; ypos < width; ypos += gridSize) {
context.moveTo(0, ypos);
context.lineTo(width, ypos);
}
for (var xpos = 0; xpos < width; xpos += gridSize) {
context.moveTo(xpos, 0);
context.lineTo(xpos, width);
}
context.strokeStyle = "#000";
context.lineWidth = 1;
context.stroke();
}
// Função para acessar o elemento Canvas do HTML, via DOM
window.onload = function(){
// Definição da variável para acessar o elemento
var canvas = document.getElementById("TreinaWebCanvas");
// Definição do contexto 2D ou 3D
var context = canvas.getContext("2d");
// Aqui vai o código para criação dos elementos gráficos
displayGrid(context);
};
</script>
</head>
<body>
<canvas id="TreinaWebCanvas" width="500" height="500"></canvas>
</body>
</html>
Desenho da Logo do TreinaWeb em Canvas
Para nos aprofundarmos um pouco mais no assunto, iremos reproduzir a logo do TreinaWeb via HTML5 Canvas. Veja abaixo a logo original, criada no Corel:

Para esta reprodução, iremos também profissionalizar um pouco nosso projeto, separando JavaScript do HTML, criando funções, etc.
Para isso, primeiro de tudo, salve o script abaixo com o nome de TreinaWeb.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Desenho da Logo do TreinaWeb com HTML5 Canvas</title>
<script type="text/javascript" src="TreinaWeb.js"></script>
</head>
<body>
<canvas id="Canvas" width="540px" height="540px"></canvas>
</body>
</html>
Agora, salve o arquivo abaixo como TreinaWeb.js, no mesmo diretório de TreinaWeb.html
window.onload = DesenhaLogo; //Seta o onload, para a nossa função
//Função que exibe a gride, conforme vimos noexemplo anterior.
//Iremos utilizá-la também neste exemplo
function displayGrid(context) {
var gridSize = 15, width = 900;
for (var ypos = 0; ypos < width; ypos += gridSize) {
context.moveTo(0, ypos);
context.lineTo(width, ypos);
}
for (var xpos = 0; xpos < width; xpos += gridSize) {
context.moveTo(xpos, 0);
context.lineTo(xpos, width);
}
context.strokeStyle = "#000";
context.lineWidth = 1;
context.stroke();
}
function DesenhaLogo()
{
//Cria contexto de trabalho
var context = document.getElementById('Canvas').getContext("2d");
//Cria um efeito de gradiente no contexto
var my_gradient = context.createLinearGradient(180, 330, 300, -100);
my_gradient.addColorStop(0, "#396393");
my_gradient.addColorStop(1, "#FFFFFF");
//Cria arco Branco, caso o fundo da página seja de outra cor
context.save();
context.beginPath();
context.arc(260,260,215,0,Math.PI*2,true);
context.closePath();
context.strokeStyle = '#FFF';
context.lineWidth = 35;
context.stroke();
//Cria argo azul, interno
context.beginPath();
context.arc(260,260,194,0,Math.PI*2,true);
context.closePath();
context.strokeStyle = '#396393';
context.lineWidth = 22;
context.stroke();
//Cria circulo e preenche com o gradiente criado anteriormente
context.fillStyle = "#396393";
context.beginPath();
context.arc(260,260,188,0,Math.PI*2,true);
context.closePath();
context.fillStyle = my_gradient;
context.fill();
//Cria o contorno do mouse, na logo
context.beginPath();
context.rotate(-0.38);
context.scale(0.58, 1);
context.arc(190, 413, 149, 0, Math.PI*2 , false);
context.arc(191, 433, 149, 0, Math.PI*2 , false);
context.fillStyle = '#FFF';
context.fill();
context.restore();
context.save();
context.beginPath();
context.arc(259,259,245,0,Math.PI*2,true);
context.closePath();
context.strokeStyle = '#396393';
context.lineWidth = 29;
context.stroke();
//Cria circulo externo, envolvendo todo o conteúdo
context.restore();
context.save();
context.beginPath();
context.rotate(-0.38);
context.scale(0.30, 1);
context.arc(358, 338, 40, 0, Math.PI*2 , false);
context.fillStyle = '#396393';
context.fill();
//Desenha botão azul do mouse, e linha dos finais dos botões
context.restore();
context.save();
context.beginPath();
context.rotate(-0.38);
context.scale(1, 1);
context.arc(120, 262, 149, Math.PI*2 -5.26, Math.PI -0.88, false);
context.strokeStyle = '#396393';
context.lineWidth = 5;
context.stroke();
//Separa os outros botões do mouse
context.restore();
context.save();
context.beginPath();
context.rotate(-0.38);
context.scale(0.3, 1);
context.arc(505, 340, 149, Math.PI *2 - 3.635, Math.PI*3/2 - 1.044, false);
context.strokeStyle = '#396393';
context.lineWidth = 16;
context.stroke();
//Salva e reinicia o contexto
context.restore();
context.save();
//Define cor e cria uma pequena correção no topo da
//linha que separa os botões do mouse
context.beginPath();
context.strokeStyle = '#396393';
context.lineWidth = 5;
context.moveTo(205,212);
context.lineTo(202,202);
context.stroke();
context.closePath();
//Define cor e espessura da linha que
//representará o fio do mouse
context.beginPath();
context.strokeStyle = '#FCFFF8';
context.lineWidth = 4.5;
//Desenha curva que representa o fio do mouse
context.beginPath();
context.moveTo(202,202);
context.quadraticCurveTo(175, 160, 184, 130);
context.quadraticCurveTo(202, 58, 325, 134);
context.quadraticCurveTo(384, 180, 365, 83);
context.stroke();
context.closePath();
}
Salve, e execute o arquivo TreinaWeb.html. Veja o resultado em execução:

Supondo agora, que você queira comparar visualmente os pixels das duas figuras, um processo bem interessante é jogar uma grid em cima de ambas. Como exemplo, vamos ativar a grid que criamos anteriormente, adicionando a linha abaixo, logo após a última linha de código da função DesenhaLogo().
displayGrid(context);
Feito isto, execute novamente o TreinaWeb.html e veja o resultado, conforme abaixo:

Com isso é possível fazer uma comparação, mesmo que não seja muito precisa, já dá pra ter uma noção geral, se as coisas estão no lugar.
Para finalizar, vamos entender um pouco sobre os principais métodos e propriedades do Canvas utilizados na reprodução da logo:
arc(x, y, raio, anguloInicial, anguloFinal, sentido) – Desenha um arco com centro nas coordenadas x, y com um raio definido e ângulo inicial e final definidos em radianos (negativos ou positivos) e o sentido que pode ser horário(false) ou anti-horário (true).
Exemplos de arcos:

fillStyle = Refere-se a cor de fundo.
stroke() – Aplica os estilos definidos pelos atributos de criação, por exemplo, aplica os estilos strokeStyle, lineWidth e etc.
quadraticCurveTo() – Desenha curvas quadráticas, que nada mais é que um método para criarmos formas personalizadas.
Pronto! Faça alguns testes, altere as cores, espessuras, formas, etc. E veja o que acontece. Caso queira se aprofundar mais neste e em outros assuntos, não deixe de fazer nossos cursos sobre HTML5, a começar pelo módulo básico: http://www.treinaweb.com.br/curso/html5-basico
