Introducción
El 7 de agosto de 2010, deviantART celebró su décimo aniversario. Para celebrar nuestro cumpleaños, lanzamos una herramienta de dibujo HTML5 llamada deviantART muro. La herramienta se puede usar como una aplicación web independiente y como una herramienta de dibujo liviana para agregar imágenes a los comentarios del foro.
La comunidad de deviantART recibió esta nueva herramienta de dibujo con gran entusiasmo, y la herramienta ahora recibe tanto tráfico como algunas propiedades web de tamaño decente. Desde su lanzamiento, se envía un dibujo nuevo a través del muro de deviantART aproximadamente cada 5 segundos. Estas son solo las cantidades de dibujos completados; muchos más se iniciaron y no se guardaron.
En el siguiente artículo, se proporcionan algunos antecedentes sobre cómo usamos HTML5, por qué elegimos usar las tecnologías que usamos y lo que descubrí mientras escribía una de las primeras aplicaciones de HTML5 completas para un sitio web importante.
Mi experiencia
A fines de 2005, fui uno de los desarrolladores responsables de la herramienta de dibujo que usaba Draw Here. La herramienta era un "graffiti web" que se iniciaba con un favorito. Se usaba para dibujar imágenes en cualquier página web. Draw Here se creó inicialmente con SVG (acababa de salir la versión beta de Firefox 1.5, uno de los primeros navegadores en admitir SVG).
En Internet Explorer, creábamos SVG en segundo plano, pero renderizábamos el dibujo con VML. En ese momento, WebKit no admitía SVG, por lo que portamos nuestro código para renderizar el SVG con canvas (que era una tecnología nueva que solo se veía en WebKit en ese momento). En un momento dado, incluso hice un puerto para que nuestro código SVG se renderizara en navegadores más antiguos con un montón de elementos div pegados. (por supuesto, esto fue más una broma para mostrar que se podía hacer y era muy lento de usar).
En su apogeo, se usaban alrededor de 100 dibujos por día. Era lo suficientemente completo como para llamarlo más que un experimento, aunque no tenía la terminación final de una aplicación web importante. A mediados de 2006, se abandonó el proyecto, aunque el sitio aún funciona, en su mayoría, solo por diversión.
Tecnologías que usa el muro de deviantART
Debido a mi experiencia con varias tecnologías HTML5 en sus inicios, me pidieron que fuera el desarrollador principal de deviantART muro. Cualquier persona que lea este artículo probablemente pueda comprender por qué decidimos usar HTML5, en lugar de una tecnología basada en complementos, como Silverlight o Flash. Queríamos algo sólido y que usara estándares abiertos.
Cómo decidir entre Canvas y SVG
Decidimos hacer la capa de dibujo con lienzo. Algunas personas pueden preguntarse cuándo deben usar canvas y cuándo SVG. Hay mucha superposición en lo que se puede hacer con las dos tecnologías. Como lo demostró Draw Here, ambas tecnologías se pueden usar para crear una aplicación de dibujo.
Descubrí que SVG es excelente si quieres conservar los controladores de los objetos que dibujaste. Por ejemplo, si deseas que el usuario pueda dibujar una línea y, luego, arrastrar partes de la línea para cambiar su forma, eso sería bastante trivial con SVG. Pero lo mismo es muy incómodo con el lienzo.
Cuando usas Canvas, envías elementos al lienzo y, luego, te olvidas de ellos. Un lienzo en blanco y uno en el que se dibujó durante una hora actúan exactamente igual en el código y tienen aproximadamente el mismo espacio en memoria. Si bien un programa de dibujo de tramas suele funcionar muy bien con la tecnología de enviar y olvidar, dificulta ciertas tareas. Por ejemplo, crear una función de deshacer rápida es mucho más difícil en el lienzo que en SVG. En SVG, puedes conservar un control de las últimas líneas que colocaste, y deshacer es solo cuestión de quitar esos objetos. Con el lienzo, una vez que se pinta una línea, no sabes qué había debajo, por lo que quitarla requiere volver a dibujar el área en la que estaba.
Una vez que nos decidimos a usar HTML5 para el lienzo, decidimos usar algunos elementos de otros elementos de HTML5 aquí y allá. Un ejemplo de esto es cómo usamos localStorage para hacer un seguimiento de la configuración del pincel del usuario. De esta manera, una vez que tengan configurados los diferentes pinceles de la forma que les guste, pueden volver a esa configuración la próxima vez que usen nuestra herramienta. localStorage significa que no tenemos que agotar nuestra cookie ni realizar ningún viaje al servidor para obtener esas preferencias.
Cómo usar Canvas
Canvas ha avanzado mucho en los últimos cinco años. Con Draw Here, en realidad, no publicamos mi puerto de lienzo porque el rendimiento no era bueno. Creo que es seguro decir que probablemente tiene un mejor rendimiento de lo que imaginas. Borrar una gran sección del lienzo y volver a dibujar formas complicadas suele ocurrir a velocidades más rápidas que la percepción humana. Lo único que encontré que, en ocasiones, es demasiado lento es usar getImageData() para muestrear píxeles. La velocidad de la operación, obviamente, depende del tamaño del lienzo, pero, en un lienzo grande, realizar una getImageData() en el momento equivocado puede tardar lo suficiente como para que un usuario sienta que la aplicación responde con lentitud.
Después de leer varios instructivos sobre Canvas, al principio tuve la impresión de que era un elemento pesado que se debía usar con moderación, tal vez una o dos veces en una página. No sé si todos tienen esta sensación, pero yo sí, así que la usé con moderación cuando comenzamos a codificar el muro de deviantART. Sin embargo, después de un tiempo, descubrí que hay muchos lugares pequeños en los que un lienzo puede ahorrarte mucho esfuerzo. Por ejemplo, las maquetas de nuestra app especificaban que debía haber un selector de color que fuera de dos triángulos superpuestos que mostraran colores primarios y secundarios:

Mi primer instinto fue empezar a pensar en una forma de crear este pequeño dispositivo de IU con HTML y CSS tradicionales. Las personas que son buenas en el hackeo de CSS podrían señalar cómo se podría hacer todo esto con CSS, pero la forma triangular de las dos partes que cambian de color hace que no sea tan obvio.
Cuando se me ocurrió usar solo un lienzo, hice el widget con un solo elemento DOM y un par de líneas de JavaScript. El muro de deviantART usa nodos de lienzo por todas partes. Cada capa es un lienzo, y cambiar el orden de las capas es solo cuestión de cambiar el índice z. La paleta del "navegador" de zoom que muestra una vista reducida del área de dibujo es solo otro lienzo que, en ocasiones, llama a drawImage() con los lienzos de capas como imágenes de origen. Incluso el cursor del área de dibujo (un círculo de dos tonos que ajusta el tamaño según el tamaño del pincel y el zoom) es un lienzo que flota debajo del mouse.
El motivo por el que fuimos más flexibles con el lienzo que con otras tecnologías HTML5 es que la biblioteca ExplorerCanvas de Google permite simular el lienzo en Internet Explorer. Eso me lleva a la siguiente sección.
Internet Explorer (IE)
El motivo principal por el que los sitios web más importantes aún no usan HTML5 es que no quieren perder a sus usuarios de Internet Explorer. Estoy seguro de que la primera pregunta que se les ocurre a la mayoría de los desarrolladores cuando escuchan que deviantART creó una aplicación de dibujo en HTML5 es: "¿Qué se hizo con IE?".
Al principio, decidimos que haríamos todo lo posible para que todo funcionara en Internet Explorer, pero que ya no usábamos el estilo de desarrollo web de denominador común. Debido a que la comunidad web adoptó el enfoque de que un sitio no se puede lanzar hasta que se vea igual en todos los navegadores conocidos, los usuarios no pueden saber cuándo su navegador no es compatible. Para el usuario promedio, los problemas de velocidad se atribuyen a su conexión a Internet, y cada página se renderiza más o menos de la misma manera. Por lo tanto, deciden cuál es su navegador favorito en función de elementos arbitrarios de la interfaz de usuario, como el color del botón Atrás.
Decidimos crear cualquier función interesante que se nos ocurriera con las especificaciones de HTML5, intentar que funcionara en Internet Explorer y, si no funcionaba, mostrar una ventana modal en la que se explicara que la función no estaba disponible porque el navegador aún no implementaba un estándar web.
En un principio, intentamos que todo funcionara con ExplorerCanvas (exCanvas) de Google. Es sorprendentemente bueno para imitar el lienzo en la mayoría de los casos. Sin embargo, tiene una desventaja. Cada trazo que se realiza en el lienzo es un objeto DOM en la traducción de VML subyacente. Esto está bien para la mayoría de las cosas que podrías intentar con el lienzo, pero algunos de los pinceles de deviantART muro crean formas a partir de la superposición de muchos trazos. Cuando Internet Explorer se enfrenta a un VML que tiene miles de nodos, incluso en una máquina rápida, falla y se bloquea. Debido a esto, para muchas de las llamadas de dibujo, tuvimos que ingresar y codificar en VML real, y usar trucos en los que concatenamos los nodos y usamos el comando de movimiento para especificar dónde deberían haber espacios. Muchos de los controles pequeños y otros elementos de la interfaz usan una etiqueta de lienzo, ya que esos pequeños usos suelen funcionar bien con exCanvas.
Además de hacer que algunas funciones funcionen con exCanvas, les sugerimos a los usuarios que podían seguir usando su versión de Internet Explorer si instalaban el complemento Google Chrome Frame. Google Chrome Frame es un complemento que incorpora el motor de renderización de Google Chrome en Internet Explorer. Desde la perspectiva del usuario, sigue usando el navegador que conoce, pero, en segundo plano, nuestra página se renderiza con las capacidades de HTML5 de Chrome y un JavaScript más rápido.
Sabía que se suponía que era fácil portar elementos para que funcionen con Chrome Frame, pero no me di cuenta de lo simple que era. Solo debes agregar una metaetiqueta adicional y… eso es todo, todo comenzará a funcionar en IE.
Resumen
Es un placer trabajar con las nuevas tecnologías de la especificación HTML5, y diría que todo lo que usé está listo para el horario estelar. Incluso si necesitas que todo funcione sin problemas en IE, hay una cantidad sorprendente de tareas que puedes realizar combinando canvas y exCanvas. Y escribir una capa de traducción entre SVG y VML también es sorprendentemente factible. Una vez que empiezas a usar la tecnología, es como entrar a un mundo completamente nuevo.
Referencias
- deviantART muro
- El foro de deviantART, en el que puedes dibujar (requiere acceso)
- ExplorerCanvas
- Google Chrome Frame