Na primeira parte, vimos alguns destes tópicos: adoção de XML e SVG, mobilidade, caixa de pintura e efeitos. Nesta, serão abordados detalhes da biblioteca Raphaël, profundidade e WebGL, entre outros assuntos.
***
Raphaël, o artista
O exemplo na figura 5 mostra as capacidades básicas de desenho da biblioteca de desenho Raphaël e demonstra como utilizar o Inkscape como auxiliar na edição das imagens. As primeiras linhas de listagem 2 contêm o cabeçalho HTML e a conexão entre o Raphaël e o jQuery.

O último não é totalmente necessário para criar trabalhos com a biblioteca Raphaël, mas o jQuery torna muito mais fácil configurar um manipulador de eventos que irá suportar qualquer navegador (linha 54) e ao mesmo tempo garante que o código JavaScript não seja executado até que a interface DOM esteja pronta para isso (função $ na linha 8). A linha 15 inicializa a área de desenho de Raphaël. A linha 17 faz um pequeno círculo (figura 6). Os métodos de desenho sempre pertencem à área de desenho do objeto. As linhas 19 a 22 criam os múltiplos segmentos da curva de Bézier. Os caminhos a seguir para o desenho seguem os padrões do SVG, que não são exatamente famosos por sua legibilidade, mas é improvável que isso seja um problema. É possível criar strings numéricas e alfanuméricas com Inkscape. Se quiser desenhar uma forma de coração com a ferramenta curva de Bézier no Inkscape, selecione o caminho e pressione Editar | Editor de XML, e simplesmente copie o conteúdo do primeiro atributo, D, como o parâmetro path(). As linhas 24 e 25 configuram o atributo de preenchimento e traçado para #ff0, o código hexadecimal para o vermelho. As linhas 27 e 29 escrevem um texto dentro do coração e o pintam de amarelo. As coisas começam a ficar mais movimentadas com as funções de animação (linhas 36 a 51), que as próximas duas linhas irão chamar uma vez para inicializar a animação.
Listagem 2: Exemplo com a biblioteca Raphaël
01 <!DOCTYPE HTML> 02 <html> 03 <head> 04 script type="text/javascript" src="raphael‐min.js"> </script> 05 <script type="text/javascript" src="jquery‐1.6.2.min.js"></script> 06 <script type="text/javascript"> 07 //jQuery run function after loading the document 08 $(function(){ 09 //Colors the ball changes between 10 var colors = ["#000", "#800", "#f00", "#f80","#ff0"]; 11 //Array counter 12 var counter = 0, zoom = 1; 13 14 //Drawing area 200x200 at position 50,50 15 var paper = Raphael(50, 50, 200, 200); 16 //Circle at position 40, 60, Radius 10 17 var circle = paper.circle(40, 60, 10); 18 //Path definition copied from Inkscape 19 var path = paper.path("m 41.416257,61.90761 c 17.95308,‐27.77874 " + 20 "56.06346,0.53741 56.06346,0.53741 0,0 38.055253,‐28.20692 " + 21 "55.982363,‐0.46836 34.96991,54.10886 ‐55.982363,112.02335 " + 22 "‐55.982363,112.02335 0,0 ‐91.0840396, ‐57.90515 ‐56.06346,‐112.0924 z"); 23 //Red for fill and outline 24 path.attr("fill", "#f00"); 25 path.attr("stroke", "#f00"); 26 //Heart‐shaped text at center 27 var text = paper.text(100, 100, "Please\nclick me!"); 28 //Text color yellow 29 text.attr("fill", "#ff0"); 30 31 //Start animations 32 animateCircle(); 33 colorChange(); 34 35 //Re‐animate the ball every 2000 ms 36 function animateCircle(){ 37 //Raphaël method for moving ball along path 38 circle.animateAlong(path, 2000, false); 39 //Reset timer 40 setTimeout(animateCircle, 2000); 41 } 42 43 //Change ball color at random intervals 44 function colorChange(){ 45 //Raphaël function changes element attributes 46 circle.attr("fill", colors[counter]); 47 //Increment elements of array colors, back to 0 if needed 48 counter = (counter < 5) ? ++counter : 0; 49 //Reset timer 50 setTimeout(colorChange, Math.random()*50); 51 } 52 53 //jQuery click handler for heart 54 $(path.node).click(function(){ 55 //> 1 ‐> zoom out and vice‐versa 56 zoom = (zoom > 0.95) ? 57 zoom ‐ 0.1: 58 zoom + 0.1; 59 //animate heart scaling with "bounce" type 60 path.animate({scale:zoom}, 500, "bounce") 61 }); 62 }); 63 </script> 64 </head> 65 <body></body> 66 </html>

Explorer 6. Sem intervenção do desenvolvedor, o Raphaël converte comandos de desenho e animações para VML, formato específico da Microsoft.
Sempre em movimento
A instrução animateCircle() na linhas 36 a 41 causa um um pequeno movimento de bola em volta da forma de coração. O método animateAlong() da biblioteca Raphaël é usado para isso. O script passa nos parâmetros (path, 2000, false), que representa o caminho existente, a duração da animação, e false para desativar a rotação do objeto, que não teria efeito visível sobre a bola. A linha 40 define um tempo limite para que a função JavaScript chame novamente a animação após seu término em um movimento de loop.
A função colorChange() conta os cinco elementos de cores e atribui a cor de preenchimento para o círculo. O parâmetro setTimeout() na linha 50, em seguida, torna-se a função para executar novamente em intervalos aleatórios. Isso passa o manipulador de cliques para o coração. Ele usa o manipulador de eventos jQuery como camada de abstração para fornecer suporte para o Internet Explorer 6 também. Mesmo nesse navegador antigo, a biblioteca Raphaël mostra o potencial de suas habilidades de desenho (figura 6). Quando o coração é clicado, é atribuído um fator de escala que oscila entre um fator 0,1 e 1 do valor original.
O código mostra que o Raphaël pode mudar muitos atributos SVG de uma só vez e suporta transições suaves. Para fazer isso, o método animate() é utilizado; ele espera um objeto que compreende atributo/pares de valores, a duração da animação, e o tipo de animação como parâmetros. bounce, quando aplicado à escala do objeto, causa um efeito no estilo de geleia balançando.
Profundidade
Há alguns anos, o VRML foi uma tentativa de incorporar recursos 3D interativos em páginas HTML. No entanto, isso não foi muito bem sucedido devido ao fato de que não havia navegadores com suporte para linguagens de modelagem 3D de forma nativa. As coisas parecem muito melhores agora para o WebGL, uma API de gráficos 3D baseado em OpenGL ES 2.0 que dá ao navegador acesso ao acelerador de hardware da placa gráfica. A atual safra de navegadores, com exceção do Internet Explorer, já suporta isso. A Microsoft afirma estar preocupada com a segurança do hardware quando seu acesso é exposto através da Internet, de modo que nenhum suporte pode ser esperado a partir de Redmond no futuro (figura 7).
WebGL: uma tecnologia 3D dos anos 80
O WebGL suporta acesso direto aos recursos do OpenGL em JavaScript. Desenvolvedores mais experientes com modelagem 3D serão capazes de fazer praticamente qualquer coisa que possa ser programada em OpenGL no navegador sem um plugin – com exceção de operações computacionalmente mais caras do tipo que os motores de jogos atuais utilizam ou então o suporte diferenciado para recursos Blender. O interpretador JavaScript simplesmente não foi projetado para computação de alto desempenho contendo vetores e matrizes, apesar de alguns progressos existirem nesse sentido nos últimos anos.
Alguns desenvolvedores web têm dificuldade para começar na programação WebGL por conta de sua abordagem de baixo nível. O princípio de design do WebGL passa muito longe das APIs orientadas a objetos de hoje – e isso não é nenhuma surpresa, já que as raízes do OpenGL remontam à década de 1980. Dito isso, existem várias bibliotecas para ajudar programadores com nenhum conhecimento em C ou GL. O GLGE e o SceneJS são muito maduros nesse sentido. Os exemplos simples presentes nas listagens 3 e 4 desenham o cubo mostrado na figura 8, com a ajuda de GLGE. O cubo é composto por duas partes: um arquivo HTML com código JavaScript e um arquivo XML que define os elementos para a o objeto 3D. O arquivo HTML (listagem 3) contém um elemento de tela e integra a biblioteca GLGE, que executa o método load(), que por sua vez carrega o arquivo XML da cena depois de inicializar o objeto (linhas 5 a 12). A função chamada nas linhas 14 a 20 fazem o trabalho pesado depois de carregada a cena. Essa função começa por inicializar a tela como o processador e a cena 3D. A variável doc contém a definição da cena como um documento XML DOM analisável (listagem 4). Ele inclui uma definição de cena com um ID de cena principal, que as linhas 16 e 17 fornecem para o renderizador. Tudo o que precisa ser feito agora é uma chamada para render(), e o navegador vai exibir um cubo com iluminação natural.
Listagem 3: Código HTML WebGL
01 <!DOCTYPE HTML> 02 <html> 03 <head></head> 04 <body> 05 <canvas id="canvas" width="300" height="300"></canvas> 06 <script type="text/javascript" src="glge‐compiled‐min.js"></script> 07 08 <script type="text/javascript"> 09 var canvasElement = 10 var doc = new GLGE.Document(); document.getElementById("canvas"); 11 12 doc.load("defs.xml"); 13 14 doc.onLoad = function() { 15 var renderer = new GLGE.Renderer(canvasElement); 16 var scene = new GLGE.Scene(); 17 scene = doc.getElement("mainScene"); 18 renderer.setScene(scene); 19 renderer.render(); 20 } 21 </script> 22 </body> 23 </html>

A definição de cena combina as coordenadas espaciais de seis triângulos para criar uma malha 3D (linhas 5 a 10). O triângulo é a forma básica da qual todos os programas 3D dependem, inclusive o GLGE. As coordenadas foram selecionadas para criar um cubo com um comprimento da aresta com valor 1. Um objeto necessita de um material de preenchimento para definir as propriedades de sua superfície. Esse exemplo apenas define os reflexos e a cor (linha 16). O elemento de cena posiciona o preenchimento, a visualização e a luz, sem a qual você não veria nada.
Movimento e luminosidade
Esse exemplo simples mostra que não há necessidade de se preocupar efetivamente com a programação caso sua opção seja usar o GLGE. O que você não vê, nesse exemplo, é do que tratam os impressionantes recursos da biblioteca: o GLGE suporta animação baseada em quadro-chave, o que também fornece um sistema de esqueleto primitivo para personagens animados.
Holofotes, pontos de luz e destaques direcionados fornecem uma iluminação realista, assim como o mapeamento normal (isto é, interpolação da iluminação entre os painéis de preenchimento). A figura 9 mostra o ambiente de mapeamento em ação. Como no exemplo, é possível abordar todos esses recursos através de uma API orientada a objetos com XML declarativo; programação OpenGL não é necessária. Para eliminar a necessidade de os desenvolvedores digitarem matrizes longas manualmente para definição de preenchimento (listagem 4, nas linhas 5 a 10), o editor Blender 3D tem dois plugins de exportação, e nenhum deles trabalha com a versão atual do Blender, a versão 2.5, em nosso laboratório.
Listagem 4: Definição de cena da figura 8
01 <?xml version="1.0"?> 02 <glge> 03 <mesh id="cube"> 04 <positions> 05 1,1,1, 1,1, ‐1, 1,1,1 , ‐1,1,-1, -1,1,1, 06 ‐1, ‐1, ‐1, ‐1, ‐1, 1, ‐1, 1, 1, ‐1, ‐1, 07 1, ‐1, ‐1, 1, ‐1, 1, ‐1, ‐1, ‐1, 1, ‐1, 08 1, 1, 1,1,1, ‐1,1, ‐1, ‐1,1,1,1, 1,1, ‐1, 1,‐1, ‐1, ‐1, 1, 1, 09 1,1,1,1,1, ‐1,1, ‐1, ‐1,1,1,1, 1,1, ‐1, 1,‐1, ‐1, ‐1, 1, 1, 10 1,1,1,1,1, ‐1,1, ‐1, ‐1,1,1,1, 1,1, ‐1, 1,‐1, ‐1, ‐1, 1, 1, 11 </positions> 12 </mesh> 13 14 <material id="cubeMat" specular="1" color="#8822bb" /> 15 <camera id="mainCamera" /> 16 <scene id="mainScene" camera="#mainCamera" ambient_color="#fff"> 17 <object id="cube" mesh="#cube" loc_x="0.5" loc_y="‐0.1" loc_z="‐10" 18 rot_x="0.8" rot_y="0.9" rot_z="‐0.1" 19 type="L_POINT" /> 20 material="#cubeMat" /> <light id="mainlight" loc_x="20" loc_y="16g" loc_z="1" rot_x="‐1.5" color="#ff8" </scene> 21 22 </glge>

Mais luz do que sombras
Se considerarmos os recentes novos desenvolvimentos na estrutura do HTML, veremos mais luzes do que sombras: o Canvas e o SVG, que agora é – finalmente – suportado pelo Internet Explorer, tornaram a linguagem de marcação para Internet uma impressionante ferramenta de desenho para interfaces web. A conformidade com os padrões dos navegadores atuais é muito melhor agora para recursos Canvas e SVG do que foi durante a guerra dos navegadores, com a atual safra de navegadores respondendo mais ou menos de acordo com as especificações atuais.