O Canvas, criado a partir do HTML5, é um elemento que pode ser usado para desenhar na tela, geralmente usando-se javascript.
Aqui, montaremos um canvas controlado pelo mouse, que irá simular uma viagem interestelar. Se você também é fã de Star Trek, vai encontrar alguns easter-eggs no código 🙂
Leia mais sobre Canvas no site da Mozilla: https://developer.mozilla.org/pt-BR/docs/Web/HTML/Canvas
A ideia foi tirada a partir do modelo:
http://kevs3d.co.uk/dev/warpfield/
Vamos ver como fazer? Primeiro vamos utilizar um pouco de CSS só pra definirmos os padrões do nosso elemento. Note que o objeto em si é bastante simples, somente uma tag de abertura e fechamento, com um ID (poderia ser uma classe, ou até mesmo sem nada).
HTML:
<canvas id="enterprise"></canvas> * Rolagem ou swipe (para cima = acelera / para baixo = desacelera)
CSS:
#enterprise { width: 350px; height: 350px; cursor: crosshair; background-color: #121212; } @media (min-width:640px) { #enterprise { width: 500px; height: 500px; } }
E agora o javascript toma conta! Primeiro vamos capturar o nosso objeto em si, que definimos pela id “enterprise”.
O contexto “2d” demonstra que o objeto não terá profundidade 3d. Pra isso, as outras opções seriam: webgl e webgl2. Existe uma última opção, bitmaprenderer, que utiliza imagens .bmp pra gerar o conteúdo.
JS:
window.onload = function(){ var canvas = document.getElementById("enterprise"), context = canvas.getContext("2d"), width = canvas.width, height = canvas.height, romulanos = width * height / 1000 * 4, dirX = width / 2, dirY = height / 2, velocidade = 60, fator = 0.03, mouse_stats = true, naves = []; //vamos popular o nosso radar de naves for (var x = 0; x < romulanos; x++) { naves[x] = { x: range(0, width), y: range(0, height), size: range(0, 1) }; } // controlador de voo (Sulu?) canvas.onmousemove = function(event) { var rect = canvas.getBoundingClientRect(), scaleX = canvas.width / rect.width, scaleY = canvas.height / rect.height; dirX = (event.clientX - rect.left) * scaleX, dirY = (event.clientY - rect.top) * scaleY; } //verifica orientação do dispositivo (mobile) if (window.DeviceOrientationEvent) { window.addEventListener('deviceorientation', function(e) { if (e.absolute) { var write; write = 'Alpha: '+ Math.floor(e.alpha); write += ', Beta: '+ Math.floor(e.beta); write += ', Gamma: '+ Math.floor(e.gamma); //escreve a orientacao e inclinacao atual document.getElementById("tilt").innerHTML = write; dirX = Math.floor((e.alpha*e.gamma)/15); dirY = Math.floor(e.beta*2); } }); } //gerencia a aceleração function MouseWheelHandler(e){ var e = window.event || e, delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail))); fator = (delta == 1) ? 0.06 : 0.009; } //addEventListener pra capturar quando houver rolagem if(window.addEventListener){ window.addEventListener("mousewheel", MouseWheelHandler, false); window.addEventListener("DOMMouseScroll", MouseWheelHandler, false); } //vamos voar! function fly(){ var origX, origY; //iniciamos o canvas limpo context.clearRect(0, 0, width, height); //e adicionamos as naves for(var x = 0; x < romulanos; x++) { origX = naves[x].x; origY = naves[x].y; //definimos os tamanhos das naves de acordo com o fator naves[x].x += (naves[x].x - dirX) * naves[x].size * fator; naves[x].y += (naves[x].y - dirY) * naves[x].size * fator; naves[x].size += factor; //se a nave atual (x) deve ser exibida, e onde if(naves[x].x < 0 || naves[x].x > width || naves[x].y < 0 || naves[x].y > height) { naves[x] = { x: range(0, width), y: range(0, height), size: 0 }; } //e aqui escrevemos a nave na tela context.strokeStyle = "rgba(255, 255, 255, " + Math.min(naves[x].size, 1) + ")"; context.lineWidth = naves[x].size; context.beginPath(); context.moveTo(origX, origY); context.lineTo(naves[x].x, naves[x].y); context.stroke(); //exibimos os detalhes do mouse, caso true if (mouse_stats) { document.getElementById("pos").innerHTML = 'Mouse em: ' + dirX + ' , ' + dirY; } } } //calcula o total a ser exibido na faixa (range) atual function range(start, end) { return Math.random() * (end - start) + start; } //atualiza o conteudo do canvas window.setInterval(fly, Math.floor(1000 / velocidade)); };
Confira a demonstração no link abaixo: