Introdução
Em 7 de agosto de 2010, o deviantART comemorou seu 10º aniversário. Para comemorar, lançamos uma ferramenta de desenho em HTML5 chamada deviantART muro. A ferramenta pode ser usada como um aplicativo da Web independente e como uma ferramenta de desenho leve para adicionar imagens aos comentários do fórum.
A comunidade do deviantART recebeu essa nova ferramenta de desenho com muito entusiasmo, e agora ela tem o mesmo tráfego de algumas propriedades da Web de tamanho decente. Desde o lançamento, um novo desenho é enviado usando o deviantART muro aproximadamente a cada 5 segundos. Esses são apenas os números de desenhos concluídos. Muitos outros foram iniciados, mas não salvos.
O artigo a seguir fornece alguns antecedentes sobre como estamos usando o HTML5, por que escolhemos as tecnologias que usamos e as coisas que descobrimos ao escrever um dos primeiros aplicativos completos de HTML5 para um site importante.
Meu plano de fundo
No final de 2005, fui um dos desenvolvedores responsáveis pela ferramenta de desenho usada pelo Draw Here. A ferramenta era um "graffiti da Web" lançado por um bookmarklet. Ele era usado para desenhar imagens em qualquer página da Web. O Draw Here foi criado inicialmente usando SVG (o Firefox 1.5 Beta tinha acabado de ser lançado e foi um dos primeiros navegadores a oferecer suporte a SVG).
No Internet Explorer, criamos SVG em segundo plano, mas renderizamos o desenho usando VML. O WebKit não oferecia suporte a SVG na época, então eu transpus nosso código para renderizar o SVG usando canvas, que era uma nova tecnologia encontrada apenas no WebKit na época. Em um determinado momento, até fiz uma porta para que nosso código SVG pudesse ser renderizado em navegadores mais antigos usando vários elementos div colados. Claro, isso foi mais uma piada para mostrar que isso poderia ser feito e era muito lento de usar.
No auge, o Draw Here era usado para fazer cerca de 100 desenhos por dia. Ele estava completo o suficiente para ser chamado de mais do que apenas um experimento, embora não tivesse o acabamento final de um aplicativo da Web importante. Em meados de 2006, o projeto foi abandonado, mas o site ainda está funcionando, principalmente para diversão.
Tecnologias usadas pelo deviantART muro
Devido à minha experiência com várias tecnologias HTML5 no início, fui convidado para ser o desenvolvedor principal do deviantART muro. Qualquer pessoa que esteja lendo este artigo provavelmente entende por que decidimos usar o HTML5 em vez de uma tecnologia baseada em plug-in, como Silverlight ou Flash. Queríamos algo robusto e que usasse padrões abertos.
Como escolher entre canvas e SVG
Decidimos fazer a camada de desenho usando a tela. Algumas pessoas podem se perguntar quando usar canvas e quando usar SVG. Há muita sobreposição no que pode ser feito com as duas tecnologias. Como o Draw Here provou, as duas tecnologias podem ser usadas para criar um aplicativo de desenho.
Descobri que o SVG é ótimo se você quiser manter as alças dos objetos que desenhou. Por exemplo, se você quiser que o usuário desenhe uma linha e, em seguida, arraste partes dela para mudar a forma, isso seria bastante simples usando SVG. Mas a mesma coisa é muito estranha usando a tela.
Quando você usa a tela, você coloca coisas nela e depois esquece. Uma tela em branco e outra que foi desenhada por uma hora se comportam exatamente da mesma forma no código e têm aproximadamente a mesma pegada de memória. Embora um programa de desenho raster geralmente funcione muito bem com a tecnologia de incêndio e esquecimento, ele dificulta algumas coisas. Por exemplo, criar uma função de desfazer rápida é muito mais difícil em canvas do que em SVG. No SVG, você pode manter um identificador para as últimas linhas colocadas, e desfazer é apenas uma questão de remover esses objetos. Com a tela, depois que uma linha é pintada, você não sabe o que estava por baixo dela, portanto, remover a linha requer redesenhar a área em que ela estava.
Depois de decidirmos usar o HTML5 para a tela, decidimos usar alguns recursos do HTML5 aqui e ali. Um exemplo disso é como usamos o localStorage para acompanhar as configurações de pincel do usuário. Dessa forma, depois que os vários pincéis forem configurados da maneira que o usuário preferir, ele poderá voltar a essas configurações na próxima vez que usar nossa ferramenta. O localStorage significa que não precisamos usar nosso cookie ou fazer viagens ao servidor para acessar essas preferências.
Como usar o Canvas
O Canvas evoluiu muito nos últimos cinco anos. Com o Draw Here, não publicamos minha porta de tela, porque a performance não era boa. Agora, acho que é seguro dizer que ele provavelmente tem um desempenho melhor do que você imagina. Limpar uma grande seção da tela e redesenhar formas complicadas geralmente pode acontecer em velocidades mais rápidas do que a percepção humana. A única coisa que achei muito lenta é o uso de getImageData() para amostrar pixels. A velocidade da operação obviamente depende do tamanho da tela, mas, em uma tela grande, fazer uma chamada getImageData() no momento errado pode levar tempo suficiente para que o usuário sinta que o aplicativo é lento para responder.
Depois de ler vários tutoriais sobre a tela, tive a impressão de que ela era algo pesado que deveria ser usado com moderação, talvez uma ou duas vezes em uma página. Não sei se todo mundo tem essa sensação, mas eu tinha, então usei com moderação quando comecei a programar o muro do deviantART. Depois de um tempo, descobri que há muitos lugares em que uma tela pode economizar muito esforço. Por exemplo, os mockups do nosso app especificavam que deveria haver um seletor de cores com dois triângulos sobrepostos mostrando cores primárias e secundárias:

Meu primeiro instinto foi começar a pensar em uma maneira de criar esse pequeno dispositivo de interface com HTML e CSS tradicionais. Pessoas que são boas em hackear CSS podem apontar como tudo isso pode ser feito com CSS, mas a forma triangular das duas partes que mudam de cor não é tão óbvia.
Quando pensei em usar uma tela, criei o widget com um único elemento DOM e algumas linhas de JavaScript. O deviantART muro usa nós de tela por toda parte. Cada camada é uma tela, e mudar a ordem das camadas é apenas uma questão de mudar o índice z. A paleta de "navegador" de zoom que mostra uma visualização reduzida da área de desenho é apenas outra tela que ocasionalmente chama drawImage() usando as telas de camada como imagens de origem. Até mesmo o cursor da área de desenho (um círculo de dois tons que ajusta o tamanho dependendo do tamanho do pincel e do zoom) é uma tela que flutua abaixo do mouse.
A razão pela qual fomos mais liberais com a tela do que com outras tecnologias HTML5 é que a biblioteca ExplorerCanvas do Google permite simular a tela no Internet Explorer. Isso me leva à próxima seção.
Internet Explorer (IE)
O principal motivo pelo qual os sites mais importantes ainda não usam o HTML5 é que eles não querem perder os usuários do Internet Explorer. Tenho certeza de que a primeira pergunta na mente da maioria dos desenvolvedores ao ouvir que o deviantART criou um aplicativo de desenho em HTML5 é: 'O que foi feito com o IE?'
No início, decidimos fazer um esforço maior para fazer as coisas funcionarem no Internet Explorer, mas não queríamos usar o estilo de denominador comum de desenvolvimento da Web. Como a comunidade da Web adotou a abordagem de que um site não pode ser lançado até que tenha a mesma aparência em todos os navegadores conhecidos, os usuários não conseguem saber quando o navegador está com problemas. Para o usuário médio, os problemas de velocidade são atribuídos à conexão de Internet, e todas as páginas são renderizadas mais ou menos da mesma forma. Então, eles decidem qual é o navegador favorito com base em pequenas coisas arbitrárias da interface do usuário, como a cor do botão "Voltar".
Decidimos criar qualquer recurso legal que nos viesse à mente usando a especificação HTML5, tentar fazer com que ele funcionasse no Internet Explorer e, se não funcionasse, mostraríamos um modal explicando que o recurso não estava disponível porque o navegador ainda não implementava um padrão da Web.
No início, tentamos fazer com que as coisas funcionassem com a ExplorerCanvas (exCanvas) do Google. Ele é surpreendentemente bom em imitar a tela para a maioria das coisas. No entanto, há uma desvantagem. Cada traço feito na tela é um objeto DOM na tradução de VML. Para a maioria das coisas que você pode tentar com a tela, isso é normal, mas algumas das pincéis do deviantART muro criam formas ao agrupar muitas pinceladas. Quando o Internet Explorer se depara com um VML que tem milhares de nós, mesmo em uma máquina rápida, ele falha. Por isso, para muitas das chamadas de exibição, tivemos que programar no VML real e usar truques em que concatenamos os nós e usamos o comando de movimento para especificar onde deveria haver lacunas. Muitos dos pequenos controles e outras coisas na interface usam uma tag de tela, já que esses pequenos usos geralmente funcionam bem com o exCanvas.
Além de fazer com que algumas coisas funcionem com o exCanvas, sugerimos aos usuários que eles pudessem continuar usando a versão do Internet Explorer se instalassem o plug-in do Google Chrome Frame. O Google Chrome Frame é um plug-in que incorpora o mecanismo de renderização do Google Chrome no Internet Explorer. Do ponto de vista do usuário, ele ainda está usando o navegador que já conhece. Mas, por trás das cortinas, nossa página é renderizada com os recursos do HTML5 do Chrome e um JavaScript mais rápido.
Eu sabia que seria fácil portar coisas para trabalhar com o Chrome Frame, mas não sabia o quão simples. Basta colocar uma metatag extra e… pronto, as coisas começam a funcionar no IE.
Resumo
É uma alegria trabalhar com as novas tecnologias na especificação HTML5. E eu diria que tudo o que usei está definitivamente pronto para o horário nobre. Mesmo que você precise que as coisas funcionem perfeitamente no IE, há uma quantidade surpreendente de coisas que você pode fazer combinando canvas e exCanvas. E escrever uma camada de tradução entre SVG e VML também é surpreendentemente possível. Quando você começa a usar a tecnologia, é como entrar em um mundo totalmente novo.
Referências
- deviantART muro
- Fórum do deviantART, onde você pode desenhar (requer login)
- ExplorerCanvas
- Google Chrome Frame