Bem, infelizmente javascript não tem muitas capacidades de gerar gráficos, linhas, pontos, círculos, etc a não ser com CANVAS (infelizmente não bem suportado por todos os navegadores) ou por POG.
Fazer usando o canvas não teria graça hehe, então fui pro que eu gosto: a velha gambiarra.
Bom, gerar o ponto é fácil:
<style> .ponto { background-color: #0000FF; position: absolute; overflow: hidden;} </style> <script> //global que guarda a largura da linha. Quanto maior, mais rápido o processamento. window['larguraPonto']=2; function geraPonto(x, y, nome, elempai) { //by Micox - www.elmicox.com - 31/01/08 var pixel = document.createElement('div'); pixel.id = nome; pixel.className = 'ponto'; pixel.style.width = pixel.style.height = window['larguraPonto'] + 'px' pixel.style.left = x + 'px'; pixel.style.top = y + 'px'; return elempai.appendChild(pixel); } //chamando a função e gerando uma reta vertical window.onload = function(){ geraPonto(10,4,'ponto1',document.body) geraPonto(10,6,'ponto2',document.body) geraPonto(10,8,'ponto3',document.body) geraPonto(10,10,'ponto4',document.body) geraPonto(10,12,'ponto4',document.body) geraPonto(10,14,'ponto4',document.body) } </script>
Perceba que eu coloquei algumas características do ponto via CSS e a definição da largura do ponto em uma variável global. Quanto MENOR for o valor da largura do ponto, logicamente irá demorar mais a plotagem do ponto.
Agora pra gerar uma linha inteira terei que usar meus exímios e velhos conhecimentos de matemática geométrica aprendidos no ensino médio hauehea (Vê se eu lembro disso. Lógico que colei do David Betz e dei umas adaptadas).
function geraLinha(x1, y1, x2, y2, nome, elempai) { //by Micox - www.elmicox.com - 31/01/08 - adaptado de http://www.davidbetz.net/graphics/ var longPixel = document.createElement('div'); if(elempai.constructor==String){ elempai = document.getElementById(elempai);} if(typeof(window['MicoxLinhas'])=='undefined'){ window['MicoxLinhas'] = Array(); //este cidadão global irá guardar todas as linhas } window['MicoxLinhas'][nome] = Array() var steep = Math.abs(y2 - y1) > Math.abs(x2 - x1); if (steep) { var t = y1; y1 = x1; x1 = t; t = y2; y2 = x2; x2 = t; } var deltaX = Math.abs(x2 - x1); var deltaY = Math.abs(y2 - y1); var error = 0; var deltaErr = deltaY; var xStep, yStep, modulo; var x = x1, y = y1; if (x1 < x2) { xStep = window['larguraPonto']; modulo = +1; }else { xStep = -window['larguraPonto']; modulo = -1; } if(y1 < y2) { yStep = window['larguraPonto']; } else { yStep = -window['larguraPonto']; } var nomeP = nome + x + '-' + y; if(steep) { window['MicoxLinhas'][nome][x] = geraPonto(y, x, nomeP, elempai); } else { window['MicoxLinhas'][nome][x] = geraPonto(x, y, nomeP, elempai); } var fim = modulo * x2; while( modulo * x < fim) { x = x + xStep; error = error + deltaErr; if(2 * error >= deltaX) { y = y + yStep; error = error - deltaX; } nomeP = nome + x + '-' + y; if(steep) { window['MicoxLinhas'][nome][x] = geraPonto(y, x, nomeP, elempai); } else { window['MicoxLinhas'][nome][x] = geraPonto(x, y, nomeP, elempai); } } return window['MicoxLinhas'][nome]; } //brincando de desenhar window.onload = function(){ geraLinha(20,120,30,100,'minhaLinha1',document.body) geraLinha(30,100,60,100,'minhaLinha2',document.body) geraLinha(60,100,90,80,'minhaLinha3',document.body) geraLinha(90,80,130,80,'minhaLinha4',document.body) geraLinha(130,80,160,100,'minhaLinha5',document.body) geraLinha(160,100,210,105,'minhaLinha6',document.body) geraLinha(210,105,220,120,'minhaLinha7',document.body) geraLinha(220,120,20,120,'minhaLinha8',document.body) //agora só faltam as rodas haehaheuhaeu }
Pronto, agora só falta fazer funções pra elipses e curvas hauheuhae. Não tô afim de brincar disso hoje não. Algum dia eu ou alguém faz uma função pra isso.
Percebam, senhores, que coloquei a opção de nomes nas linhas e pontos e coloquei elas dentro de um pai qualquer. Pra quê? Ué, pra poder apagar e mover as ditas cujas.
As funções de apagar:
function removePonto(nomeOuRef){ //recebe o ID do ponto ou a referencia ao objeto HTML if(nomeOuRef.constructor==String){ nomeOuRef = document.getElementById(nome); } nomeOuRef.parentNode.removeChild(nomeOuRef) try { delete nomeOuRef; } catch(e) { nomeOuRef = null } } function removeLinha(nomeOuRef){ //recebe o ID da reta ou a referencia ao objeto array if(nomeOuRef.constructor==String){ nomeOuRef = window[nomeOuRef]; } for(var i in nomeOuRef){ removePonto(nomeOuRef[i]) try { delete nomeOuRef[i]; } catch(e) { nomeOuRef[i] = null } } try { delete nomeOuRef; } catch(e) { nomeOuRef = null } }
As funções de mover nem precisava colocar aqui pois é aquele básico esquema de mover Divs:
function move(quem){ //by Micox - www.elmicox.com - 30/01/08 if(quem.constructor==String){ quem = document.getElementById(quem); } //movendo window['move'+quem.id] = setInterval( function(){ quem.style.left = (quem.offsetLeft + 5) + 'px' }, 50); } function para(quem){ //by Micox - www.elmicox.com - 30/01/08 if(quem.constructor==String){ quem = document.getElementById(quem); } if(typeof(window['move'+quem.id])=='number'){ clearInterval(window['move'+quem.id]) } }
Agora veja um exemplo completo e meu opalão se movimentando aqui.
- "Porra mico, que mané você heim? Não é mais fácil abrir um programa de imagens qualquer e desenhar diboas?"
- Sim meu caro cidadão, porém, digamos que você queira fazer um fluxograma em javascript (aqui você vê o fluxograma finalizado). E aí? Nunca se sabe quando vamos precisar de algo, como diria George Boole.
Té a próxima, malucada.
Gostou da dica acima? Então clica nos botões de compartilhamento abaixo e me ajude a dica a subir no Google.
Exelente texto
ResponderExcluirCara, parabéns! Muito legal este algoritmo. Peguei esta ideia para colocar num site (ainda em construção) de cursos online. Isto vai me ajudar muito na hora em que for pedido para o aluno construir, por exemplo, um botão. Abraços, Eduardo Scopel.
ResponderExcluirEssa gera um círculo:
ResponderExcluirfunction geraCirculo(x,y,r,nome,elempai,precisao){
//by Will - 0w0w7w@gmail.com - 23/03/13
var longPixel = document.createElement('div');
if(precisao == undefined){
precisao = 5;
}
if(elempai.constructor==String){ elempai = document.getElementById(elempai);}
if(typeof(window['WillCirc'])=='undefined'){
window['WillCirc'] = Array(); //este cidadão global irá guardar todos os circulos
}
window['WillCirc'][nome] = Array()
var nomeC = nome + x + '-' + y;
var ang = 0;
var x2;
var y2;
//usa seno e cosseno para gerar o círculo, sem segredo, so tem que converter para radianos
var tmp_x=x+Math.cos(Math.PI/(180/ang))*r;
var tmp_y=y+Math.sin(Math.PI/(180/ang))*r;
while(ang < 360){
ang=ang+precisao; //define a precisao
x2 = x+Math.cos(Math.PI/(180/ang))*r;
y2 = y+Math.sin(Math.PI/(180/ang))*r;
//faz circulos que ficam com falhas quando grandes
//window['WillCirc'][nome][ang] = geraPonto(x2,y2,nomeC,elempai);
geraLinha(tmp_x,tmp_y,x2,y2,nomeC,elempai);
//faz coisas interessantes...excetos circulos
//geraLinha(tmp_x,tmp_y,x2,y2,nomeC,elempai);
tmp_x=x2;
tmp_y=y2;
}
//document.write('teste: '+Math.sin(Math.PI/(180/30)));
return window['WillCirc'][nome];
}
a chamada é assim:
window.onload = function(){
document.onclick = function(){
var pY = window.event.clientY;
var pX = window.event.clientX;
geraCirculo(pX,pY,250,'Circ1',document.body);
};
};
tudo isso dentro da tag script
Ponha dentro do head do html
Impressionante Will. Vou atualizar o post.
Excluir