Gracias al increíble trabajo del equipo de Disney y Vectorform, en solo un mes han conseguido poner en marcha el nuevo sitio llamado "Disney TRON: Legacy Digital Book Site", una experiencia envolvente basada en HTML5 que aprovecha la capacidad de aceleración de gráficos por hardware de Internet Explorer 9.
En este post me gustaría contar algunas anécdotas y vivencias en la trastienda que ha vivido el equipo encargado del proyecto, poniendo especial énfasis en ciertas lecciones y buenas prácticas de implementación que hemos aprendido a partir de esta experiencia. Quisiera agradecer en concreto a Ken Disbennett, director creativo, y Alex Barkan, jefe de Desarrollo de Vectorform, que han accedido a compartir sus experiencias y sus ideas sobre el proyecto con nosotros.
Los contenidos originales nos los habían entregado en forma de archivos Photoshop de alta resolución, organizados por capítulos y páginas.
Nos llevó unos 5 días de trabajo bastante meticuloso el tener que independizar cada personaje y los demás elementos esenciales del fondo en cada viñeta del cómic. Dibujamos el escenario de fondo para dotar a las escenas de un aspecto natural y fluido. Tuvimos que reconstruir cada viñeta por orden siguiendo la disposición lineal y orgánica del sitio web. Finalmente aislamos cada elemento y lo exportamos en diversas posiciones para generar el producto final animado.
Nuestra primera idea fue utilizar CSS3 (concretamente las transformaciones 2D de CSS3). Empezamos por crear unos cuantos tests simulando el nivel de interacción que necesitábamos para este proyecto utilizando CSS3. Lo más difícil era la interacción mediante programación sin pérdida de rendimiento. Estuvimos probando diversas alternativas y experimentando con Javascript puro, animaciones con JQuery, con optimización de los dibujos y aprovechando los recursos del DOM y CSS; en ningún caso pudimos obtener el rendimiento deseado de 60 frames por segundo (FPS) en ningún navegador.
No contentos con el rendimiento de CSS3, buscamos una solución basada en el elemento <canvas> de HTML5. A partir de un proyecto nuestro anterior (el sitio web Foursquare HTML5 Playground), diseñamos un nuevo prototipo para someter a prueba el rendimiento del navegador. El prototipo funcionaba con suavidad, con un rendimiento de 60 FPS en equipos de oficina de gama baja. Podíamos gestionar 10.000 edificios y presentar en pantalla cientos de imágenes PNG de 32 bits de resolución en color RBGA con funcionalidad básica de recorte en la ventana de presentación. El momento del "aleluya" llegó cuando pudimos añadirle figuras animadas utilizando el método del canvas llamado drawImage() en su versión que permite el troceado de imágenes (se explica más adelante). Incorporamos cientos de personajes animados que, en nuestros entornos de prueba intensivos, se movían entre cientos de edificios. Estaba claro: el <canvas> de HTML5 en Internet Explorer 9 (y en menor grado en otros navegadores también), ¡era otra cosa!.
Una de las cosas que aprendimos fue a obtener resultados muy aceptables en RGBA de 8 bits a partir de RGBA de 32 bits. Componemos la imagen en forma de dos capas independientes: una textura de base y otra de brillo. Después comprimimos ambas como RGBA de 8 bits. Con esto conseguimos unos rangos muy grandes para representar brillos (pensemos en la luz de las farolas en medio de la niebla), pero eliminamos 16 bits de datos por cada triplete RGB. El resultado es que el tamaño total del archivo es muy inferior al de un PNG de 32 bits RGBA y una calidad muy superior a la que nos ofrece un archivo único RGBA de 8 bits. Aquí vemos el brillo de un coche en la primera página (la imagen completa se puede ver en la sección ‘Navegando por el código con las Herramientas de Desarrollo’).
Las imágenes con las que teníamos que trabajar llevaban varias capas, todas con modos de empaquetado diferentes y algunas necesitaban retoques manuales para añadirles fondos de escena que faltaban. Nuestros artistas Ken y John tuvieron que convertir todas las imágenes a los modos de empaquetado habituales de Photoshop para que se pudieran ver correctamente en los navegadores web. Además incorporaron los fondos de escena donde hizo falta e hicieron un notable trabajo con los pixels disponibles que tenían para darles un aspecto nítido. Nos dimos cuenta de algo importante: necesitábamos una pantalla de presentación de tamaño fijo para poder generar animaciones que mostrasen el relato de una manera que tuviera sentido y fuera divertido. En todo el tiempo que duró el proyecto, este ha sido un problema crucial que había que resolver: cómo conseguir unas animaciones basadas en transiciones suaves que funcionaran igual en tamaños de ventana distintos, independientemente de la sensibilidad del ratón y con la ayuda de una precarga de imágenes de fondo.
Al final nos quedamos muy impresionados con el soporte para aceleración de gráficos por hardware que tiene Internet Explorer 9; la restitución de las imágenes dentro del Canvas 2D ha demostrado un rendimiento extraordinario. En última instancia, en otros navegadores hemos obtenido también buenos resultados, pero utilizando otros mecanismos en máquinas de menos prestaciones.
Se utiliza un único bucle de dibujo (Draw(), dentro del archivo experience.js) que se encarga de dibujar todos los paneles visibles en pantalla (y también, en su caso, de la información de debug).
Nota: mientras revisas el código, puedes hacer más legible la parte de Javascript activando la opción "Format JavaScript" en las herramientas de desarrollo (pulsando F12)
Durante la fase de carga se muestra en pantalla un circulito que da vueltas. Esto lo conseguimos con una técnica de animación de figuras. La animación se define dentro de una imagen (loading-base-128.png , que para que se vea en pantalla la hemos girado 90º aquí) como una serie infinita de pasos en bucle. A medida que vamos dibujando la imagen en el Canvas, cambiamos la ventana de dibujo para mostrar solo un estado cada vez y aumentamos el lapso de tiempo según se necesite.

<meta name="application-name" content="Tron: Legacy HTML5" />
<meta name="msapplication-tooltip" content="Enter Tron: Legacy" />
<meta name="msapplication-navbutton-color" content="#00CCFF" />
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
var canvas = document.createElement('canvas');
if (!canvas.getContext) {
// The browser doesn't support HTML5 Canvas
}