Tecnologia

HTML5 Canvas: Renderização fora da tela (Offscreen Rendering)

Por: , março 17, 2014

Introdução

Este post é a segunda parte de uma série sobre HTML5 Canvas. Na primeira parte falei sobre o empilhamento de estados. Neste artigo apresentarei a técnica de Offscreen Rendering e demonstrarei uma aplicação útil usando esta técnica: O Spritebuffer. Os dois métodos importantes para o Offscreen Rendering são getImageData() e putImageData().

This article is also available in english.

O que significa Offscreen Rendering?

A tradução de Offscreen Rendering é “Renderização fora da tela”. Em outras palavras significa que algum conteúdo está sendo pintado em algum local que não é a tela. O conteúdo no contexto de Canvas representa dados gráficos que estão sendo renderizados na memória, sem visualização. Um outro termo usado é Pre-rendering (Pré-renderização). Geralmente esta técnica é usada para melhorar a experiência visual, tais como melhorias na reatividade ou no desempenho de execução. A renderização na memória é muito mais rápida do que a renderização na tela, e isso fica mais evidente quando é utilizado o método drawImage(), como está demonstrado na comparação de performance no JsPerf.

Como se aplica o Offscreen Rendering?

A renderização na tela se aplica para elementos Canvas somente embutidos no DOM. Os elementos Canvas que não estão inseridos no DOM não ficam visíveis na tela. Por isso a aplicação desta técnica é apenas gerar um elemento Canvas dinamicamente, sem inserção no DOM. Veja o seguinte código:

 [gist id=”9601617″]

Beleza, renderizei algo na memória. E agora?

Agora chegou a parte interessante: pegar o conteúdo da memória e colocar na tela. A API providencia dois métodos para copiar e colar dados gráficos de um Canvas a outro. GetImageData() copia uma área rectangular de um Canvas e putImageData() cola o conteúdo copiado em outro. Assim fica muito fácil de copiar dados gráficos entre Canvas diferentes.

 [gist  id=”9601705″]

Aplicar transformações afins nos dados gráficos

Infelizmente os dados colados com putImageData() não podem ser transformados com rotate(), scale(), translate(), ou setTransform(). Os métodos getImageData() e putImageData() são operações de baixo nível, que não afetam o estado do contexto (vide empilhamento de estados). Para que os dados possam ser transformados é necessário “pintar” os mesmos em um canvas intermediário; este novo canvas pode ser renderizado com o método drawImageData(). Sim, você leu certo: drawImageData() aceita também um objeto Canvas como argumento e o trata como se fosse uma imagem.

Criar canvas intermediário para que possa ser tratado como uma imagem normal.

O seguinte código demonstra o conceito de Canvas intermediário.

 [gist id=”9602456″]

O resultado apresentado fica semelhante a imagem abaixo:

Sprite

Caso de uso: Spritebuffer

Um caso de uso comum para a técnica de Offscreen Rendering é o Spritebuffer. Um sprite é um objeto gráfico móvel, que está sendo pintado em cima de outros objetos. Geralmente sprites são empacotados em imagens maiores, e um único Sprite é copiado do pacote para a tela. Para obter Sprites transformáveis é preciso utilizar a técnica do Canvas intermediário. O seguinte código é um exemplo de uso e implantação de um Spritebuffer. A “classe” está pronta para uso, sendo assim sinta-se livre para copiá-la e reutilizá-la.

[gist id=”9602484″]
 

  • Receba nosso conteúdo em primeira mão.