> Manuales > Taller de HTML5

La trastienda de la película TRON de Disney: Cómo crear un sitio Web de animación con HTML5.

Enlace: http://tron.vectorform.com/

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.

Del papel a la web (Ken Disbennett)

Todo empezó a partir del libro impreso del cómic. El objetivo consistía en aprovechar la potencia de HTML5 para actualizar esa experiencia sin perder el sentido de autenticidad de la experiencia tradicional del cómic. Pretendíamos asegurarnos de que cada viñeta del cómic cobraba vida y acción por sí misma, como en la versión impresa, y que el sitio web daba la sensación de hilo argumental a lo largo de todo el relato. Por ello decidimos que una experiencia lineal, basada en línea de tiempo, sería lo mejor. Cada viñeta se debería hacer con un aspecto propio y personal que pusiera de relieve y reforzara la narración. El sentido de avance de izquierda a derecha a lo largo del cómic se mantenía fiel a la forma habitual de lectura, pero sin tener que interrumpirla para pasar las páginas.

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.

Elección de la tecnología adecuada (Alex Barkan)

Estuvimos cinco días creando unos cuantos prototipos que nos ayudasen a identificar la tecnología de base más adecuada para este proyecto y que ofreciera los mejores resultados en todos los navegadores.

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!.

Reducir el ancho de banda sin perder calidad (Alex Barkan)

El ancho de banda necesario era un problema obvio desde el primer momento. Queríamos imágenes en alta definición: montones de pixels, altas tasas de transmisión y una transparencia lo más natural posible. Para lograr que funcionase bien el efecto de paralaje necesitábamos superponer múltiples capas con transparencia superior a 1 bit, porque si no, las imágenes no podrían tener mayor calidad que la que dan los GIFs. El formato PNG era la opción evidente –aunque costosa. Pero mientras íbamos avanzando, John Einselen (Director artístico de Vectorform) se hizo con una herramienta muy útil llamada pngquant. A día de hoy todos los navegadores soportan el PNG/8, una variación muy poco utilizada del formato PNG donde la información de color RGB y de transparencia (Alpha) se puede guardar dentro del mismo canal de 8 bits, lo que nos permitiría disponer de valores de transparencia de varios bits para conseguir una presentación mucho más realista en pantalla pero ¡reduciendo el tamaño de los archivos a la mitad!. Tuvimos que hacer una serie de pruebas para ver si este sistema de cuantización era adecuado para nuestro sitio y que no perdíamos demasiada calidad de imagen con respecto al original.

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.

Sincronización y aceleración (Alex Barkan)

Un problema habitual en las animaciones que afecta a todas las tecnologías (CSS, HTML, Canvas) es qué hacer con la sincronización vertical. Lo complicado aquí es que cada navegador tiene una resolución de reloj distinta, con un margen de error que puede ser mayor o menor. Debido a esto, podemos tener una parte del código dibujando en un buffer de imagen mientras se va dibujando la pantalla. A fin de evitar las interrupciones y “ruidos” visuales, tuvimos que afinar al máximo la llamada a la función setTimeout() en los procesos de dibujo para ajustar el proceso a una frecuencia de refresco de pantalla de 60 Hz. Desde luego, ya nos gustaría poder hacerlo de forma más fácil en todos los casos. Espero ver pronto cómo marchan los trabajos en el W3C al respecto de requestAnimationFrame.

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.

Navegando por el código con herramientas de desarrollo

A fin de mantener la flexibilidad, modularidad y manejabilidad de la aplicación, toda la narración se ha dividido en 13 "páginas" distintas (igual que en el libro original). Las páginas se precargan durante el arranque de la aplicación y se disponen una tras otra sobre un eje horizontal. Cada página define su propia presentación y lógica de interacción, relativa al eje horizontal (que se configura durante el proceso de arranque).

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)

Modo de depuración

Casi todas las páginas incluyen información de debug que nos ha ayudado durante la fase de desarrollo. Concretamente, podemos ver en pantalla el contador de rendimiento de frames por segundo pulsando la letra "d" del teclado. En la consola (pulsando F12 y seleccionando la pestaña de la Consola), aparece más información de debug.

Nota: en la aplicación tenemos otra tecla oculta, ¿quieres averiguar cuál es y qué hace?

Precarga de imágenes

En la carga de la primera página, cada página solicita de forma asíncrona los recursos necesarios para la clase preloader definida en experience.js. El preloader se encarga del encolamiento y descarga de todos los recursos utilizados en el proyecto.

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.

¿Cómo sabemos que esta imagen está preparada antes que las demás? Es fácil: la cargamos antes que todas las demás y hacemos que su tamaño sea relativamente pequeño.

Mantener los tipos de letra originales

El conservar los mismos tipos de letra del cómic original era un requisito fundamental para la aplicación. Después de probar con el formato WOFF, decidimos utilizar FontSquirrel.com para empaquetar las fuentes WOFF (y otros formatos para su uso en caso de error) y generar el snippet de código @font-face que necesitábamos.

Anclado del sitio IE9 a la barra de tareas

Con unas cuantas líneas más de código podíamos mejorar la experiencia de usuario de este sitio web aún más, en caso de utilizar Internet Explorer 9. Este sitio se puede anclar a la barra de tareas de Windows 7 (basta con arrastrar y dejar la pestaña en la barra). Utilizamos BuildMyPinnedSite.com para crear un icono en alta resolución del sitio web (que incluye tamaños de 16x16, 24x24, 32x32 y 64x64 pixels).

<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" />

Tests e interoperabilidad

Para poder ver este sitio correctamente se necesita que el navegador soporte las etiquetas <canvas> y <audio> de HTML5 y también las directivas WOFF de CSS3. Como resultado de nuestras pruebas, aunque Internet Explorer 9 nos ofrece la mejor y más rápida experiencia, hemos conseguido que se vea correctamente en Firefox, Safari, Chrome y Opera. Hemos incorporado una técnica de detección de funcionalidad para identificar los navegadores antiguos que no tienen capacidad para mostrar esta página:

var canvas = document.createElement('canvas');
if (!canvas.getContext) {
// The browser doesn't support HTML5 Canvas
}

Giorgio Sardo

Evangelista Técnico Senior | HTML5 e Internet Explorer

Manual