Desenhando com Canvas do HTML5
em
[ Migrado do LetsHack It ]
Alguns de vocês podem ter visto que tive alguns pequenos projetos usando o Canvas do HTML5 na EnergyLabs Brasil. Abaixo alguns projetos que fazem uso do Canvas:
Porém nunca expliquei a ninguém como os fiz. Vou começar um simulador de gráficos onde você digita a fórmula e ele desenha o gráfico, e explicarei no caminho o que estou fazendo.
Acredito que será útil para muitas pessoas.
Bom irei postar como iniciar o Canvas e irei dormir. Mais tarde continuarei este post do Lets Hack It!
Para inicializar o Canvas:
<script type="text/javascript> var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); </script> <center><canvas id="myCanvas" width="640" height="480">Seu browser não suporta canvas!</canvas></center>
Entre as tags **
É isso ai, mais tarde explico mais de como desenhar. Irei dormir agora! Boa madrugada a todos 😀
——————————————————————————-
Não consegui fazer nada hoje praticamente. Acordei tarde e tive de sair correndo por que ainda tinha que deixar algo nos correios.
De qualquer maneira começarei agora a escrever, talvez não termine hoje, mas irei adiantar o máximo possível.
Vamos lá, cometi um erro no post anterior, as vars precisam ser declaradas dentro da função draw() por um motivo simples, o browser interpreta linha a linha o código javascript, e o javascript está antes da declaração da tag canvas. executaremos a função draw no método onLoad da tag body. Assim quando ele carregar tudo, executará o Draw e tudo funcionará perfeitamente.
Vamos lá, começar a desenhar, pintando o fundo de preto.
Dentro da tag script, colocaremos o seguinte:
var width = 640; var height = 480; function draw() { var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = '#000000'; ctx.fillRect(0,0,width,height); }
Definimos duas variáveis width e height para definirmos a largura e altura. Note que alterar esses valores não altera o tamanho do canvas, e sim a área onde nosso script desenhará. Se você for fazer uma tela de desenho diferente, não se esqueça de alterar a tag canvas também!
Isso deve resultar nisso:
A função fillStyle define a cor do preenchimento como diz o próprio nome. Ela segue o mesmo padrão do HTML sendo cada cor composta de um byte em hexa ( 00 a FF ) no padrão RRGGBB ( R = Vermelho, G = Verde, B = Azul ).
Já a função fillRect faz o preenchimento de um retângulo, seu uso é:
fillRect(StartX,StartY,EndX,EndY);
Onde:
StartX, StartY -> São as coordenadas do ponto superior esquerdo.
EndX, EndY -> São as coordenadas do ponto inferior direito.
Simples não?
——————————————————————————-
Vamos começar a desenhar as linhas e colunas então. Para isso criaremos uma “caneta” para desenhar no canvas.
Usaremos basicamente 5 comandos do canvas:
beginPath() => Inicia a operação “caneta” do canvas
moveTo(x,y) => Move a caneta para coordenada x,y
lineTo(x,y) => Marca o desenho da posição atual da caneta até x,y
stroke() => Efetua o desenho marcado
closePath() => Finaliza a operação “caneta” do canvas
Então vamos lá!
Mudaremos o tamanho do Canvas para 640×640 para termos uma área de desenho quadrada. Altere o width e height tanto no javascript quanto na tag canvas para este tamanho. Também alteraremos a cor usada anteriormente para preenchimento do fundo, para algo ligeiramente diferente do preto, no meu caso usei o #333333
Faremos tudo a uma relação para que haja uma linha e uma coluna cruzando exatamente no centro da tela. Tendo uma tela de desenho 640×640, a sua coluna central começará em (0,width/2) e terminará em (height,width/2). Já sua linha central começará em (height/2,0) e terminará em (height/2,width). Vamos fazer tudo baseado nessa informação.
Montaremos então 5 colunas e 5 linhas, isso da uma distância de 128px entre elas. Vamos lá:
Antes de mais nada começaremos então a operação “caneta”:
ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = '#EEEEEE';
Iniciada a operação caneta, podemos começar a projetar as colunas:
var i; for(i=-2;i<=2;i++) { ctx.moveTo(width/2-128*i,0); ctx.lineTo(width/2-128*i,height); }
Vejam que eu usei uma fórmula na coordenada, onde a posição X da coluna será a largura dividida por 2 (centro) menos 128px vezes o numero da coluna. Começando por -2 (2 colunas antes da central) teremos a primeira coluna em X = largura/2 – 256.
Faremos agora as linhas, de maneira semelhante:
for(i=-2;i<=2;i++) { ctx.moveTo(0,height/2-128*i); ctx.lineTo(width,height/2-128*i); }
Após isso, podemos mandar desenhar e encerrar a operação caneta.
ctx.stroke(); //Desenhar ctx.closePath();
Isso nos resultará em algo desse jeito:
——————————————————————————
Bom vamos desenhar algo agora então no gráfico. Uma função senoidal amarela.
Uma função senoidal é definida por y = seno(x). Para fazermos este desenho, teremos que fazer um método chamado varredura. Como funciona? Simples!
Na escola quando vamos desenhar o gráfico de uma função, não pegamos vários valores de X, calculamos o Y e colocamos no plano cartesiano? Faremos algo bem semelhante aqui.
Considere que o X é número de pixels na horizontal e o Y é o número de pixels na vertical. Bem, na vertical ficará meio pequeno então faremos um controle de amplitude (“altura” da função). Cada 1 de Y valerá 10px…
Vamos começar então!
Usaremos a função translate para alterar o ponto de origem para o centro da tela (width/2,height/2). Outro detalhe é que precisamos de uma interpolação para desenhar a onda bem. Faremos o seguinte então, temos metade da janela disponível para desenho da onda, isso da width/2 para o X. Faremos uma interpolação de 100 vezes para calcular os valores de seno.
ctx.translate(width/2,height/2); ctx.beginPath(); ctx.strokeStyle = '#EEEE00';
ctx.moveTo(0,0); var x=0;; var amplitude = 0; while(x < width*50) { amplitude = Math.round(Math.sin(x/100)*100); ctx.lineTo(x/5,amplitude); x++; } ctx.stroke(); ctx.closePath();
Começamos traduzindo o X e Y para width/2 e height/2 respectivamente, logo o 0,0 será o centro da tela (cruzamento da linha e coluna centrais).
Movemos a caneta para 0,0 e fizemos um laço iterativo que roda até o x ser igual a cinquenta vezes a largura da tela [lembra que falei da interpolação? Considerando que onde desenhamos é largura/2, largura*50 é uma interpolação de 100 vezes]. A variável amplitude é usada para armazenar o valor do Y, onde usamos o Math.sin(x/100) [Lembra da interpolação? Aqui temos que usar o x no tamanho real da tela!] e multiplicamos por 100 [lembra que falei que cada Y valeria 100px?] após isso arredondamos com o Math.round, afinal não existe pixel em números fracionários. Feito isso teremos um resultado assim:
Viram como é “fácil”?
Podemos fazer umas alterações também!
ctx.translate(0,height/2); ctx.beginPath(); ctx.strokeStyle = '#EEEE00'; ctx.moveTo(0,0); var x=0; var amplitude = 0; while(x < (width/2)*100) { amplitude = Math.round(Math.sin(x/100)*300); ctx.lineTo(x/2,amplitude); x++; }
Isso irá gerar um resultado assim:
Para clarificar um pouco as mudanças que fiz, aqui está um código que ficará mais fácil de entender o que cada coisa faz:
var PosX = 0; var PosY = height/2; var Interpolacao = 100; var AmplitudeM = 300; var Periodo = 2; ctx.translate(PosX,PosY); ctx.beginPath(); ctx.strokeStyle = '#EEEE00'; ctx.moveTo(0,0); var x=0; var amplitude = 0; while(x < (width/2)*Interpolacao) { amplitude = Math.round(Math.sin(x/Interpolacao)*AmplitudeM); ctx.lineTo(x/Periodo,amplitude); x++; } ctx.stroke(); ctx.closePath();
Defini variáveis antes para esclarecer a devida função de cada coisa:
PosX => Posição X real do 0 no plano cartesiano
PosY => Posição Y real do 0 no plano cartesiano
Interpolacao => Numero de pontos para a interpolação
AmplitudeM => Multiplicador de amplitude
Periodo => Divisor do Período
Faça uma alteração você mesmo nesses valores e veja a diferença!
Podemos fazer qualquer fórmula nisso, veja só o resultado de y = seno(x)*sqrt(x)
Tente você também!
Código: