Animación de imágenes de fondo de forma programática
Existen dos formas principales en que las personas animan las imágenes de fondo:
- Usa sprites de CSS para actualizar un
background-position
en JS . - Hacks con
.toDataURL()
.
La primera funciona muy bien si tienes la imagen con anticipación, pero ¿qué sucede si tu fuente debe generarse de forma programática, por ejemplo, con un <canvas>
? La solución para el problema 1 es usar .toDataURL()
en el lienzo y establecer el fondo en la URL generada:
while(1) {
var url = canvas.toDataURL('image/jpeg');
el.style.background = 'url(' + url + ')';
}
Esto tiene dos problemas:
- Las URLs de
data:
agregan una sobrecarga de tamaño de alrededor del 33% a la imagen resultante. - Una gran cantidad de toques de DOM (
el.style
).
Ambos métodos son ineficientes: no son aceptables para una app web que siempre tenga una fluidez de 60 fps.
Cómo usar un lienzo 2D como fondo

Resulta que hay una API no estándar que WebKit tiene desde hace años y que puede tomar el lienzo como fuente de un fondo. Sin embargo, no hay especificaciones publicadas para esta función.
Primero, en lugar de especificar una URL para el botón Atrás, haz lo siguiente:
.bg {
background: url(bg.png) no-repeat 50% 50%;
}
Usa -webkit-canvas()
y haz referencia a un identificador de cadena a un contexto de lienzo:
.canvas-bg {
background: -webkit-canvas(animation) no-repeat 50% 50%;
}
A continuación, debemos crear el contexto 2D con una versión especial de .getContext()
:
var ctx = document.getCSSCanvasContext('2d', 'animation', 300, 300);
Más información de Dave Hyatt:
Animaciones
Como se ve en la demostración, podemos volver a usar requestAnimationFrame()
para controlar una animación. Esto es genial, ya que, una vez que todo está conectado, se conserva la asociación entre CSS y el elemento del lienzo. No es necesario manipular el DOM.
¿La demostración no se anima en Chrome?
El canal estable actual de Chrome (versión 23) tiene crbug.com/161699, que impide que una animación requestAnimationFrame()
actualice el fondo correctamente. Este error se corrigió en Chrome 25 (actualmente Canary). La demo también debería funcionar bien en la versión actual de Safari.
Beneficios de rendimiento
Estamos hablando de lienzo. Las animaciones aceleradas por hardware ahora están completamente disponibles (al menos para los navegadores en los que funciona esta función). Y, solo para reiterar, no es necesario molestar al DOM desde JS.
Cómo usar WebGL como fondo
Espera un momento. ¿Esto significa que podemos potenciar un fondo de CSS con WebGL? Por supuesto que sí. WebGL es solo un contexto 3D para Canvas. Solo cambia "experimental-webgl" en lugar de "2d" y listo.
var gl = document.getCSSCanvasContext('experimental-webgl', 'animation', 300, 150);
Aquí tienes una prueba de concepto que contiene un div con su fondo dibujado con sombreadores de vértices y fragmentos: DEMO
Otros enfoques
Vale la pena señalar que Mozilla tiene -moz-element()
(MDN) desde hace bastante tiempo. Esto forma parte de la especificación del nivel 4 del módulo de valores de imágenes y contenido reemplazado de CSS y te permite crear una imagen generada a partir de HTML arbitrario: videos, lienzos, contenido del DOM, etc. Sin embargo, existen problemas de seguridad relacionados con el acceso completo a las imágenes de instantáneas del DOM. Esta es la razón principal por la que otros navegadores no adoptaron esa función.