Como escolher Canvas ou SVG para seus Websites

Aqui vou compartilhar com vocês algumas reflexões que podem ajudar à hora de escolher entre Canvas e SVG, ou uma mistura de ambos.

Por Patrick Dengler-Tradução CRV


Publicado em: 14/8/12
Valorize este artigo:
Canvas e SVG são duas funcionalidades de gráficos tremendamente interessantes que aparecem com Internet Explorer 9 e ambas se beneficiam da aceleração por hardware. Estas tecnologias nos podem servir para resolver numerosos cenários de uso de gráficos das webs atuais. À vista da grande expectativa que Canvas ocasionou, parece que a tendência é ignorar SVG que, em muitos dos casos, é uma opção melhor.

Breve resumo de Canvas e SVG

A continuação, resumo em linhas gerais o que são SVG e Canvas para delimitar a análise e determinar melhor quando convém utilizar uma tecnologia de gráficos vetoriais ou outra.

Comparação entre Canvas e SVG
Canvas SVG
Orientado ao pixel (o canvas é basicamente um elemento de imagem com um API de desenho) Baseado no modelo de objetos (os elementos SVG são similares aos elementos HTML)
Elemento HTML individual, similar em seu comportamento à etiqueta <img> Múltiplos elementos gráficos que passam a fazer parte do Modelo de Objeto de Documento (DOM)
A representação visual é criada e modificada por programa, mediante scripting A representação visual é gerada a partir do markup e se modifica mediante CSS ou por programa, mediante scripting
O modelo de evento/interação com o usuário é básico exclusivamente a nível do elemento canvas; as interações se devem programar manualmente a partir das coordenadas do mouse O modelo de evento/interação com o usuário se baseia no objeto a nível de elementos gráficos primitivos ?linhas, retângulos, rotas
O API não suporta a acessibilidade; devem utilizar-se, além do canvas, outras técnicas baseadas em markup O markup SVG e o modelo de objeto suportam acessibilidade de forma nativa

O SVG é conhecido como um modelo de gráficos em modo retido que persiste dentro de um modelo em memória. De uma maneira similar a HTML, SVG gera um modelo de objeto de elementos, atributos e estilos. Quando o elemento <svg> aparece em um documento HTML5, funciona igual a um bloco "inline" e faz parte da árvore de documento HTML.

Canvas é um mapa de bits com uma interface de programação de aplicações (API) para gráficos em modo imediato para poder desenhar sobre ele. O canvas segue o modelo de "dispare e saia" que restitui os gráficos diretamente dentro de seu mapa de bits e que não tem consciência das formas que foram desenhadas na tela. O único que permanece é o mapa de bits resultante.

Podemos pensar que o Canvas vem a ser o mesmo que o API GDI de Windows, onde por programa podemos desenhar gráficos na janela, e SVG viria a ser o que é a linguagem HTML com elementos, estilos, eventos e programação baseada em DOM. Canvas se orienta a procedimento e SVG é declarativo.

Cenários de uso

Nos apartados seguintes explico as vantagens e limitações desde o ponto de vista técnico de ambas tecnologias, e também acrescento algumas orientações de sentido comum para saber em que momento interessam uma ou outra para uma tarefa específica. Na ilustração seguinte se mostra o espectro de usos que vai desde Canvas a SVG com um ponto claro ambivalência no meio.


Espectro de casos de uso de tecnologias de gráficos Canvas e SVG

Documentos vetoriais complexos de alta fidelidade

Os documentos vetoriais complexos de alta fidelidade foram e continuam sendo o campo natural de ação para SVG. Um elevado nível de detalhe na apresentação e impressão, tanto a nível de objeto individual como embebido em uma página web. A natureza declarativa de SVG é a base para a criação de ferramentas ou para a geração de formas tanto no cliente quanto no servidor a partir de informação armazenada em bases de dados.

Vejamos um exemplo tomado da demo Diagramas do mundo real que se encontra no Website Internet Explorer Test Drive:

A primeira imagem mostra os diagramas, e a segunda mostra os mesmos diagramas com uma ampliação da imagem do 1000%

Se o que você valoriza é a conveniência de observar um esquema de grande tamanho sobre o qual há que aprofundar em distintos grafos de detalhe, ou imprimir todo o documento em um formato de um tamanho específico mas mantendo as proporções e a definição, a qualidade de "escalável" dos Gráficos Vetoriais Escaláveis (SVG por suas siglas em inglês Scalable Vector Graphics) se torna evidente. É por isto que colocamos os documentos vetoriais complexos de alta fidelidade no extremo SVG do espectro

SVG como formato de imagens

Outro uso frequente de SVG é o de geração de imagens estáticas dentro da página web. Com os monitores atuais de alta densidade de pixels, os desenvolvedores devem ter em conta a qualidade dos gráficos. As imagens que se mostram a continuação representam possíveis imagens de vinhetas correspondentes a listas desordenadas "<li>" cujo estilo se determina mediante CSS. As seguintes imagens são praticamente iguais em tamanho e apresentação.


À esquerda , um gráfico SVG e à direita , uma imagem em formato PNG

Se o desenvolvedor quer mostrar a imagem em uma escala maior, ou se o usuario final utiliza uma tela de muito alta resolução, a imagem raster aparece pixelada, e necessitará uma versão de maior tamanho desse mesmo arquivo, para poder manter a fidelidade a esta escala.


Gráfico SVG ampliado à esquerda , imagem de 4K em formato PNG aumentada à direita

Portanto, SVG nos pode servir como um substituto avantajado inclusive as imagens mais simples em uma página web. No entanto o Canvas não serve como substituto.

No outro extremo do espectro, o canvas traz velocidade aos cenários de uso onde não se exige reter informação dos elementos desenhados na tela. Quando se introduziu por primeira vez a etiqueta <canvas> se começaram a desenhar experimentos muito divertidos. Eu os classifico em três categorias.

Manipulação de pixels

Já que Canvas tem que ver fundamentalmente com o desenho e manipulação a nível de pixel de uma superfície, existem certos experimentos e exemplos de Canvas com sofisticados algoritmos que conseguem uns efeitos gráficos realmente impressionantes, como por exemplo simulação de raios de luz refletidos ou filtrados.

O exemplo seguinte, chamado "Ray-Tracing" foi criado por Adam Burmister. Neste experimento se gera uma imagem à base de calcular o trajeto dos raios da luz por todo o campo de pixels em um plano da imagem e simulando os efeitos de seu reflexo sobre outros objetos virtuais dentro da cena.

O próprio autor avisa: "consome muita CPU. O navegador pode parecer que deixa de funcionar". Assim que, embora mediante o API de canvas, se possam gerar imagens como esta, não parece o mais recomendável. O próprio autor do website Adam Burmister o resume, "Ray-Tracing [é] a pior aplicação que já foi escrita em JavaScript."

O mesmo se pode dizer para outra manipulação de pixels a nível de toda a cena. A função seguinte substitui os pixels de cor verde em um canvas com pixels de outro canvas de tamanho idêntico. Uma função como esta pode servir para criar um efeito que, no mundo do vídeo, se chama "chroma".

function GreenScreenAtoB(a, b) {
    var aImageData = a.getImageData(0, 0, a.canvas.width, a.canvas.height);
    var bImageData = b.getImageData(0, 0, b.canvas.width, b.canvas.height);
    var aPixels = aImageData.data;
   var bPixels = bImageData.data;

    if (aPixels.length != bPixels.length) {
       window.alert("Canvases do not have the same number of pixels");
       return bImageData;
   }

    var pixelCount = bPixels.length;
    for (var pixelIndex = 0; pixelIndex < pixelcount; pixelIndex += 4) {
       // grab the RGBA components of each pixel in b
       var r = bPixels[pixelIndex + 0];
       var g = bPixels[pixelIndex + 1];
       var b = bPixels[pixelIndex + 2];
       var a = bPixels[pixelIndex + 3];

       // if the b pixel is green, replace it with a pixel from a
       if (r == 0 && g == 255 && b == 0 && a == 255) {
          bPixels[pixelIndex + 0] = aPixels[pixelIndex + 0];
          bPixels[pixelIndex + 1] = aPixels[pixelIndex + 1];
          bPixels[pixelIndex + 2] = aPixels[pixelIndex + 2];
          bPixels[pixelIndex + 3] = aPixels[pixelIndex + 3];
       }
    }

    return bImageData;
}

Era um experimento bastante divertido, mas como acontecia com o exemplo de reflexo da luz "ray-tracing" anterior, seu rendimento nas máquinas atuais é bem ruim. Menciono-os aqui sobretudo por uma razão: esta manipulação de pixels é, simplesmente, impossível com SVG. Este é o fator diferencial entre ambas tecnologias. Uma manipula pixels, a outra manipula objetos dentro de um modelo.

Quer se trate de criar imagens realistas a partir de gráficos vetoriais que em sua origem são simples, ou para fazer efeitos tipo chroma com vídeos, estes cenários de uso de gráficos, na maioria das vezes, simplesmente não estão ainda maduros a ponto de colocá-los na Web nos dias de hoje. No entanto, outros casos de uso sim oferecem uma boa resposta (por exemplo, a aplicação de filtros para eliminar os olhos vermelhos nas fotos). Estes casos de manipulação de pixels ficariam no extremo da esquerda de nosso espectro, como exemplos inequívocos de uso de canvas.

Cenários mistos e ambivalentes

O grupo mais interessante de casos de uso não se decide de maneira clara por nenhuma das duas tecnologias. Podemos exemplificá-lo com dois cenários básicos: diagramas/gráficos/mapas e jogos em duas dimensões.

Os gráficos e diagramas requerem gráficos vetoriais, e aqui podem valer tanto Canvas como SVG. Não obstante, SVG é frequentemente uma opção mais conveniente, dadas suas qualidades naturais.

Cenários de uso de SVG com gráficos, diagramas e mapas

Algumas das famílias mais conhecidas de gráficos e diagramas que podemos ver na Web são:
  • Os diagramas de fluxo e organogramas interativos
  • Mapas interativos e desenho de rotas ótimas
  • Planos de construção e distribuição na planta
  • Esquemas de engenharia
  • Mapas de localização de assentos em linhas aéreas e organização de eventos
  • Gráficos financeiros ou de qualquer outra natureza a partir de dados (gráficos de barras, colunas, linhas, pizzas, donuts, etc.)
Em todos estes casos a tecnologia mais adequada é SVG:
  • Estes gráficos podem ser gerados facilmente a partir de dados mediante transformações de XML a SVG
  • as versões estáticas se podem exportar mediante ferramentas (por exemplo Inkscape, Adobe Illustrator, Microsoft Visio e alguns programas de CAD)
  • Exigem precisão na interação com o usuario
  • Os criadores das webs podem personalizar módulos de outros fabricantes utilizando layouts de estilos CSS
  • Cumprem com os requisitos de acessibilidade
Para ilustrar de maneira mais precisa tudo isto, vamos ver um exemplo onde selecionamos um estado em um mapa dos Estados Unidos.

O mapa detalhado do Alaska mostrado aqui é de dominio público e pode ser encontrado em Wikimedia Commons.

Em SVG o estado de Alaska está representado como um elemento <path> com aproximadamente 162.500 elementos de dados de geometria em seu atributo "d".

<path id="AK" fill="#cdc3cc" d="M 777.5514,1536.1543 C 776.4904,1535.0933 776.7795,1530.0041 777.9416,1529.2859 C 781.3258,1527.1943 787.2657,1532.4522 784.8317,1535.3849 ..." />

Se empregamos o canvas, esta mesma forma se pode criar mediante uma serie de chamadas em Javascript:

function drawAlaska() {
    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");
    ctx.beginPath();
   ctx.moveTo(777.5514, 1536.1543);
   ctx.bezierCurveTo(776.4904, 1535.0933, 776.7795, 1530.0041, 777.9416, 1529.2859);
    ctx.bezierCurveTo(781.3258, 1527.1943, 787.2657, 1532.4522, 784.8317,1535.3849);
    //
    // 2,875 more path-drawing directives
    //
    ctx.bezierCurveTo(1689.8261, 12.13753, 1689.1395, 12.17333, 1685.8848, 10.52683);
    ctx.closePath();
    ctx.fillStyle = "#cdc3cc";
    ctx.fill();
}

Em realidade necessitamos 2.878 instruções de desenho de linhas (moveTo, lineTo e bezierCurveTo) para poder desenhar este mapa do Alaska. Obviamente, podem ser desenhadas versões de baixa resolução deste mapa. E para desenhar os estados de Wyoming e do Colorado, são necessárias bem menos linhas de código?

As aplicações de mapas baseadas em SVG normalmente incluem uma experiência de interatividade com resposta a eventos de passagem do cursor por cima, seleção de áreas, deslocamento de alguns elementos para outros mediante o tabulador e mudanças de escala. Estas operações só necessitam conceitos HTML de escassa complexidade quando utilizamos SVG, como, por exemplo, para processar um evento de mouse:

<path id="AK" fill="#cdc3cc" onmousedown="window.alert('Alaska');" d="M 777.5514,1536.1543 ..." />

Ou para criar um efeito de iluminação ao passar o cursor, que pode ser feito com CSS:

path#AK:hover { fill: yellow; }

Um exemplo destes tipos de mapas interativos pode ser visto na demo de Testdrive chamada Atlas zur Europawahl 2004 in Deutschland, uma apresentação sobre mapa dos resultados das eleições para o Parlamento Europeu de 2004 na Alemanha.

Em um canvas, a criação de qualquer destes efeitos nos obriga a programar por nossos próprios meios a detecção dos eventos e a captura das coordenadas do cursor dentro do objeto gerador do evento do mouse. Aqui já não podemos utilizar o contexto da forma. Embora exista o API isPointOnPath(), só se aplica ao último traço criado.

O código pode existir ?de fato existe- em forma de bibliotecas gráficas que permitem a detecção de eventos específicos nos gráficos utilizando os dados dos pixels para identificar a passagem do cursor e as pressões do mouse, e são plenamente funcionais. Existem também para SVG e conseguiremos um melhor rendimento se estiverem desenhadas para aproveitar as características próprias de SVG.

Diagramas e gráficos com Canvas

Também o canvas tem suas opções quando se trata de diagramas e gráficos. Para fixar o contexto neste caso, temos que comparar o rendimento de SVG e de Canvas.

Algumas vezes se produzem influencias externas que nos obrigam a escolher uma tecnologia que é, ou em principio deveria ser, independente da funcionalidade. No caso de SVG e Canvas, há dois elementos diferenciais básicos.

O conhecimento do desenvolvedor, suas competências e os elementos de apoio que tem à mão desempenham um papel muito importante à hora de decidir entre uma ou outra tecnologia. Se no caso do desenvolvimento de um jogo os programadores costumam ter um excelente nível de conhecimentos sobre as APIs de gráficos de baixo nível e um conhecimento limitado das tecnologias Web, a tecnologia que provavelmente escolherão será Canvas (vamos ver isto depois com mais detalhes). Se se trata de migrar jogos, existem ferramentas que suportam a conversão desde implementações de terceiros a Canvas.

Se o rendimento é um fator essencial, frequentemente na classe dos milissegundos, será preciso comparar o rendimento de ambas tecnologias. Isto não significa que Canvas, que habitualmente se considera de alto rendimento, seja a opção natural. Não obstante, no caso das aplicações que envolvem grandes quantidades de dados que devem ser representados a nível de pixel, o Canvas é, sem sombra de dúvida, a melhor opção.

O mapa de tempo que aparece aqui não requer uma área de desenho muito grande e o número de objetos na tela é bastante elevado. Com Canvas isto pode ser desenhado de maneira rápida sem o custo que representa a atualização da árvore do DOM.

Ainda que a imagem anterior também possa ser feita com SVG utilizando elementos como círculos e elipses para desenhar os pontos, o tempo necessário para carregar milhares de elementos no DOM é feito, inevitavelmente, muito mais lento. Sempre que vejamos um número muito grande de pixels ou imagens, uma boa recomendação é utilizar a tecnologia de Canvas ?tanto se se trata de astronomia como de movimentos de biologia celular ou espectros de modulação da voz. Os limites de velocidade na visualização dos dados são marcados pela velocidade da CPU e da implementação do Canvas e do motor de Javascript que utilizemos.

Jogos em duas dimensões

Os jogos ocasionais são o cenário más complicado de analisar. Algumas observações preliminares:
  • As bibliotecas de jogos incluem APIs de gráficos de baixo nível otimizadas
  • As competências dos desenvolvedores no mundo dos jogos estão muito orientadas para o uso destas APIs de baixo nível
  • Muitos jogos se baseiam quase exclusivamente ou em uma grande parte, em imagens ou sprites
  • Os fabricantes como Adobe começam a dar suporte a Canvas como um formato de exportação
  • Os jogos ocasionais na costumam requerer técnicas sofisticadas de captura de eventos de mouse
  • Os jogos ocasionais não têm normalmente um número exageradamente grande de "objetos"
Nas bibliotecas gráficas, como por exemplo os conhecidos motores de efeitos de física, o modelo de gráficos é independente e os gráficos se convertem em um detalhe da implementação. Os elementos de geometria como bordas, velocidades, tamanhos e posições são enviados aos motores e estes respondem em consequência com velocidades, colisões e posições. Os gráficos se utilizam unicamente para representar na tela a cena previamente calculada.

A ideia de que a parte gráfica seja independente da lógica de jogo está bem demonstrada em dois jogos desenvolvidos pelo mesmo autor, com o objetivo de ilustrar as capacidades de SVG e Canvas: SVG-oids y canvas-pinball.

Embora ambos jogos e suas lógicas sejam distintos, ambos utilizam o mesmo motor de física, que serve para controlar as posições, colisões, velocidades e outros aspectos físicos de seus componentes. Em um caso se utiliza SVG para desenhar (ou mover) os elementos do jogo, e no outro, se redesenham sobre um Canvas.

A maior parte dos jogos ocasionais em 2D que podemos ver atualmente para HTML5 utilizam o Canvas, de modo que vamos deixar este caso de uso no lado do Canvas à esquerda do ponto de cruzamento.

O cenário misto

Os jogos ocasionais também caem dentro do cenário misto porque podemos aproveitar uma combinação de características de ambas tecnologias. No caso da detecção fácil de eventos de mouse e interação com o usuário, uma camada quase opaca de geometrias SVG pode ser utilizada para colocar os elementos ao passo que um Canvas por debaixo pode servir para localizar de maneira mais rápida as imagens principais (por exemplo, as paisagens de fundo) e gerar animações em tempo real.

Cada vez encontramos mais experiências à parte do segmento dos jogos ocasionais nas quais é mais interessante o modelo de uso misto. Quando em um cenário nos encontramos com a necessidade de dispor gráficos dinâmicos e animações com qualidade alta (Canvas) junto com uma interação forte com o usuário (SVG), o recomendável é utilizar as duas tecnologias. Isto é o que se pode ver no website Brain Power de um de nossos partners, que faz parte do catálogo de sites recomendados em The Beauty of the Web. O site Brain Power ? como alguns outros mais recomendados também em The Beauty of the Web? é um exemplo de delicado equilíbrio.

Para resolver a interação do usuário e visualizar as partes do cérebro, neste site se aproveitam as geometrias de alto nível de SVG:

<polygon id="SensoryCortex" points="253,80,266,93,..." style="fill: rgba(0,0,0,0)" />

Para as animações e efeitos especiais em tempo real, se utilizam canvas:

<canvas id="cnvDisplay" width="1920" height="1099" style="position:absolute;" />

Conclusão

A análise das tecnologias de gráficos vetoriais disponíveis nas últimas versões dos navegadores nos mostra como se podem criar novos cenários de uso utilizando as tecnologias Web standard de forma interativa. Recomendo os seguintes vídeos onde se oferecem mais detalhes sobre o desenvolvimento com Canvas e SVG:

A evolução Web segue seu curso, incorporando gráficos cada vez mais sofisticados como um componente natural. Expliquei aqui meu ponto de vista sobre a aplicação destas tecnologias a casos de uso específicos. Ao final, tanto Canvas quanto SVG são componentes muito importantes dentro de uma Web cada vez mais voltada para os gráficos avançados com HTML5.

Gostaria de saber como você está aplicando estas novas tecnologias HTML5 em seus Web sites. Inclui as URLs e por favor, comprove que sua página funciona em IE9 incluindo o meta doctype, <!DOCTYPE html>, e utiliza a detecção de características em vez da detecção do navegador para saber se o Canvas ou o SVG estão suportados.






Usuários :    login / registro

Manuais relacionados
Categorias relacionadas
O autor
Patrick Dengler-Tradução CRV
Senior Program Manager, Internet Explorer

Home | Sobre nós | Copyright | Anuncie | Entrar em contato