Porque a chave no Javascript deve ser aberta na linha de cima

O Visual Studio, além de ser uma IDE mega pesada, tem um problema que gera intrigas entre equipes: ele abre por padrão uma função no JavaScript colocando a chave na linha de baixo.

Parece algo mínimo, mas irrita profundamente quem está acostumado a trabalhar da forma correta.

Porque forma correta? Simples, porque pode dar erro se colocar a chave na linha de baixo.

Pensem na função abaixo getUser que retorna um objeto em JavaScript

function getUser(){
	return {
		nome:'Danilo',
		idade:28
	}
}

getUser() // retorna um objeto

Se fosse pra deixar a chave embaixo, ficaria assim:

function getUser()
{
	return 
	{
		nome:'Danilo',
		idade:28
	}
}

getUser() // retorna undefined

Só que há um problema: pelo fato do ponto e vírgula indicando quebra de linha ser no JavaScript ser opcional, o return não entende que é pra retornar um objeto e encerra a função ali, retornando undefined.

E tem um caso pior, que simplesmente dá erro de sintaxe:

function getPosition()
{
   return 
   {
       top:32,
       left:50
   }
}
// dá erro "SyntaxError: Unexpected token :"

E se fosse feito com os braces na linha de cima, daria certo.

O incrível é que mesmo com esse argumento, tem programador que não dá o braço a torcer e insiste dizendo que JavaScript veio do java e no java se programa assim. ERRADO, JavaScript veio de Scheme e qualquer livro de Padrões em Javascript vai aconselhar abrir o bloco com a chave na linha de cima.

Dá pra configurar isso no Visual Studio 2010 (no 2008 deve dar também).

Desenhando com a tag canvas em HTML5

A maioria das pessoas (inclusivo programadores front end) vê alguma aplicação onde é possível desenhar e pensa que é algo do capeta, complexo e precisa de 1 ano pra fazer, mas provavelmente ninguém nunca tentou. É simples!

Obviamente precisa de um belo work-around pra funcionar em interfaces touch e o pior, versões antigas de IE. Mas a ideia em si é simples, basicamente no mousemove em cima do canvas você escreve uma linha com o LineTo, veja abaixo como ficou:

Bom, vamos aos códigos:

HTML

Criando a tag canvas e deixando uma mensagem caso o usuário não tenho um browser compatível com HTML5.

<canvas id="canvas" class="canvas" width="400" height="400">
    Seu browser não suporta canvas, é hora de trocar!.
</canvas>

Javascript

São só 29 linhas (bem indentadas e organizadas) de javascript

var Draw = {
	obj : document.getElementById('canvas'),
	contexto : document.getElementById('canvas').getContext("2d"),
	_init:function(){
		Draw.obj.onmousemove = Draw._over;
		Draw.obj.onmousedown = Draw._ativa;
		Draw.obj.onmouseup = Draw._inativa;
		Draw.obj.onselectstart = function () { return false; };
	},
	_over:function(e){
		if(!Draw.ativo) return;
		Draw.contexto.beginPath();
		Draw.contexto.lineTo(Draw.x,Draw.y);
		Draw.contexto.lineTo(e.layerX, e.layerY);
		Draw.contexto.stroke();
		Draw.contexto.closePath();
		Draw.x = e.layerX;
		Draw.y = e.layerY;
	},
	_ativa:function(e){
		Draw.ativo = true;
		Draw.x = e.layerX;
		Draw.y = e.layerY;
	},
	_inativa:function(){
		Draw.ativo = false;
	}	
}
Draw._init();

CSS

Basicamente, é adicionar o cursor no elemento Canvas

#canvas{ cursor: url("../img/pencil.gif"), default; }

Então, não parece tão complicado, parece?

[]s,

Como usar requestAnimationFrame ao invés de setInterval

Um grande passo pra evolução do HTML não precisar de plugins como Flash e Silverlight pra renderizar conteúdo e fazer animações ou jogos é a implementação de um controle de frames (além da aceleração por hardware que hoje já está presente em algumas features do CSS3).

Quando se fala em jogos e animações, pensamos em quantidade de frames por segundo, ou seja, quantas vezes por segundo algo vai mexer na tela.

Uma quantidade razoável pro trabalho não ficar “pesado” ou “travado” é cerca de 30 frames por segundo. Enquanto o máximo que o olho humano consegue distinguir é em torno de 60 frames por segundo, ou seja, não adianta fazer uma animação com intervalo de 10 milisegundos, seu olho não vai enxergar isso.

Antes, pra fazermos uma animação, trabalhávamos com o setInterval fixo de X milisegundos, ou então, criavamos e chamavamos uma função que se auto-invocava novamente com setTimeout também com um valor fixo de X milisegundos. O problema é que esse X de milisegundos varia de acordo com cada browser, cada processador e alguma hora acabava ficando ou muito lento, ou muito rápido.

Hoje, é possível trabalhar com o requestAnimationFrame, e ao invés de você gerenciar intervalo para o processamento, o browser faz isso.

Imaginem uma função onde algo, sei lá, um boneco, ande.

Como seria com setTimeout?

funcion mover(){
    var boneco = document.getElementById('boneco');
    boneco.style.left = (parseInt(boneco.style.left.replace('px','')) + 2).toString() + 'px';
}
setInterval(mover,20); // reinvoca a cada 20 miliseg.

Já com requestAnimationFrame seria assim:

funcion mover(){
    var boneco = document.getElementById('boneco');
    boneco.style.left = (parseInt(boneco.style.left.replace('px','')) + 2).toString() + 'px';
    mozRequestAnimationFrame(mover); 
}
mover();

Nesse caso funcionaria só pra Firefox, mas tem uma função já que funciona cross-browser e pra usuários de browsers sem HTML5 tem um work-around com setTimeout:

window.animationFrame = (function(){
	return	window.requestAnimationFrame       || 
		window.webkitRequestAnimationFrame || 
		window.mozRequestAnimationFrame    || 
		window.oRequestAnimationFrame      || 
		window.msRequestAnimationFrame     || 
		function(/* function */ callback, /* DOMElement */ element){
			window.setTimeout(callback, 1000 / 60);
		};
})();

Nesse caso, ficaria assim:

funcion mover(){
    var boneco = document.getElementById('boneco');
    boneco.style.left = (parseInt(boneco.style.left.replace('px','')) + 2).toString() + 'px';
    animationFrame (mover); 
}
mover();

Detalhes

Quando você troca de aba com o requestAnimationFrame, o processamento da animação / jogo / whatever é pausado na hora, e quando você volta, ele retorna.

Já no setInterval, hoje, pra dar uma melhor performance nos browsers, a maioria deles quando você troca de tab, ele automaticamente aumenta qualquer setInterval pra 1000 milisegundos se você ter declarado menos do que isso, e retorna ao valor inicial quando a aba é ativada novamente

Entendendo melhor o console do firebug

O console do firebug é uma poderosa ferramenta que além de mostrar erros de JavaScript, erros 404 e todos os detalhes de uma requisição ajax, é capaz de interagir com o próprio firebug, inspecionando os nodes HTML.

Mas o uso maior do console, é pra debugar javascript mesmo.

Vou listar alguns comandos, funcionam tanto no Firebug pro Firefox, quando no “Developer Tools” do Google Chrome

console.log ou console.debug

Sintaxe: console.log(variaveis);
Serve para: debugar variáveis no javascript ao invés de colocar 300 alerts

Até hoje, nunca descobri a diferença (se é que existe) entre os dois métodos.
Um detalhe que pouca gente sabe, é que é possível passar infinitos argumentos nessa função.

var nome = 'Danilo';
var sobrenome = 'Augusto';
var nome_completo = nome+' '+sobrenome;
console.log(nome_completo);
// Danilo Augusto
console.log('nome:',nome);
// nome: Danilo
console.log('nome:',nome,' e sobrenome: ',sobrenome);
// nome: Danilo e sobrenome: Augusto

console.dir

Sintaxe: console.dir(objeto);
Serve para: debugar um objeto, mostrando todos os childs dele

var posicoes = {
    left:10,
    top:50
}
console.dir(posicoes);
// left	10
// top 50

Ou então:

console.dir(document.getElementById(‘menu’));

retorna tudo sobre o elemento:

copy

Sintaxe: copy(variavel);
Serve para: copiar uma variável para a área de transferência do sistema operacional (funciona como um ctrl+c)

copy(document.getElementById('erro').innerHTML)

$0

Sintaxe: $0
Serve para: retornar o objeto selecionado/inspecionado no próprio firebug.

$0.style.display = 'none';

$$

Sintaxe: $$(expressao)
Serve para: retornar um ou mais objetos através de um seletor.

Funciona como o $ do jQuery. Então, é ideal pra testar em sites que não usam jQuery (sacou? sacou?).

$$('#footer').style.display = 'none';

inspect

Sintaxe: inspect(elemento)
Serve para: inspecionar no próprio firebug um elemento HTML.

Funciona como o $ do jQuery. Então, é ideal pra testar em sites que não usam jQuery (sacou? sacou?).

inspect($$('#footer'));

Acho interessante quem gostou do assunto dar uma olhada num vídeo do Paul Irish em que ele demonstra essas e outras funções do console do firebug.