Olá pessoal, tudo certo?!
O que acham de um “passeio” no espaço. Esta é a proposta do post de hoje : – )
Live demo: http://users.cjb.net/livedemoelemarjr/starfield.htm
Código-fonte completo: https://gist.github.com/1305213
Preparando o Canvas…
Nada novo no HTML. Observe:
Ainda utilizo o velho artifício de “monitorar” o tamanho do browser para forçar com que o canvas o ocupe integralmente..
var canvas = $("#target"); var context = canvas.get(0).getContext("2d"); var canvasWidth = canvas.width(); var canvasHeight = canvas.height(); $(window).resize(resizeCanvas); function resizeCanvas() { canvas.attr("width", $(window).get(0).innerWidth); canvas.attr("height", $(window).get(0).innerHeight); canvasWidth = canvas.width(); canvasHeight = canvas.height(); }; resizeCanvas();
O objeto “Star”
Se estamos voando em um “starfield”, nada mais natural que criar uma classe para representar uma estrela. Observe:
function randomInRange(min, max) { return Math.abs(Math.random()) * (max - min) + min; } function Star() { this.x = randomInRange(-20, 20); this.y = randomInRange(-20, 20); this.z = randomInRange(0, 32); this.size = 0; this.shade = 0; this.update = function () { with (this) { z -= 0.2; if (z <= 0) { x = randomInRange(-20, 20); y = randomInRange(-20, 20); z = 32; } size = (1 - z / 32.0) * 5; shade = parseInt((1 - z / 32.0) * 255); } }; this.draw = function () { k = 128 / this.z; px = this.x * k + (canvasWidth / 2); py = this.y * k + (canvasHeight / 2); if (px >= 0 && px <= canvasWidth && py >= 0 && py <= canvasHeight) { context.fillStyle = "rgb(" + this.shade + ", " + this.shade + ", " + this.shade + ")"; context.fillRect(px, py, this.size, this.size); } }; }
Como estamos em um espaço 3D, cada estrela tem uma posição, um tamanho e um índice de sombreamento. Cada estrela recebe uma posição inicial “aleatória”. Repare que dou uma “profundidade” máxima de 32 para cada estrela.
Quanto mais “na frente” está uma estrela, mais “branca” ela deve ser. Defino um método chamado update que aproxima a estrela do usuário, atualiza seu tamanho e sombreamento.
O método draw, calcula uma posição de tela para a estrela levando em consideração a “profundidade” da mesma no espaço 3D.
Inicializando o campo e começando a animação
Já temos nossa classe para “estrela”. Agora, é iniciar o campo e disparar a animação. Veja:
var stars = new Array(512); function loadContent() { for (var i = 0; i < stars.length; i++) stars[i] = new Star(); animate(); } loadContent(); function animate() { context.clearRect(0, 0, canvasWidth, canvasHeight); for (var i = 0; i < stars.length; i++) { stars[i].update(); stars[i].draw(); } setTimeout(animate, 33); }
Como sempre, centralizei a carga de conteúdo em uma função chamada loadContent. Além disso, disparo um laço infinito (em ~30FPS) que atualiza e desenha cada estrela.
Era isso.
outubro 22nd, 2011 → 11:41
[...] de um “passeio nas estrelas”, volto a tratar de fractais com [...]