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
Olá Danilo, boa tarde.
Estou estudando htm5 e box2d focado no desenvolvimento de jogos, porem estou tendo um pouco de dificuldades em encontrar algo em relacao ao box2d
se vc puder me ajudar fico grato.
:)
Na realidade essa técnica se torna útil, por exemplo, quando o site executa uma animação pesada e quando o usuário troca a guia ou minimiza o navegador a função para de ser executada.
Como o próprio nome diz ela é feita para animações, logo em jogos deve-se ter ou um loop com setTimeout/setInterval para o loop de jogabilidade e o requestAnimationFrame para a animação do mesmo.
O que me lembra da época que eu estava criando um site com um player e pensei em usar essa função para atualizar o tÃtulo da página: não funciona, pois quando o usuário troca a guia a música continua, mas a função para de rodar.