Images de fond basées sur un canevas

Animer des images de fond de manière programmatique

Il existe deux principales façons d'animer des images de fond :

  1. Utilisez des sprites CSS pour mettre à jour un background-position en JS .
  2. Hacks avec .toDataURL() .

La première méthode fonctionne très bien si vous avez l'image à l'avance, mais que se passe-t-il si votre source doit être générée de manière programmatique, par exemple par un <canvas> ? La solution au problème 1 consiste à utiliser .toDataURL() sur le canevas et à définir l'arrière-plan sur l'URL générée :

while(1) {
    var url = canvas.toDataURL('image/jpeg');
    el.style.background = 'url(' + url + ')';
}

Cette approche pose deux problèmes :

  1. Les URL data: ajoutent environ 33% de taille à l'image résultante.
  2. Beaucoup d'interactions avec le DOM (el.style).

Ces deux méthodes sont inefficaces et inacceptables pour une application Web à 60 FPS toujours fluide.

Utiliser un canevas 2D comme arrière-plan

Démonstration de l&#39;utilisation du canevas comme arrière-plan
DÉMO

Il s'avère qu'il existe une API non standard que WebKit utilise depuis des années et qui peut utiliser un canevas comme source d'arrière-plan. Malheureusement, aucune spécification n'a été publiée pour cette fonctionnalité.

Tout d'abord, au lieu de spécifier une URL pour le dos :

.bg {
    background: url(bg.png) no-repeat 50% 50%;
}

utilisez -webkit-canvas(), en référençant un identifiant de chaîne à un contexte de canevas :

.canvas-bg {
    background: -webkit-canvas(animation) no-repeat 50% 50%;
}

Ensuite, nous devons créer le contexte 2D avec une version spéciale de .getContext() :

var ctx = document.getCSSCanvasContext('2d', 'animation', 300, 300);

Informations supplémentaires de Dave Hyatt :

Animations

Comme vous l'avez vu dans la démo, nous pouvons réutiliser requestAnimationFrame() pour animer un élément. C'est très intéressant, car une fois les éléments connectés, l'association entre le CSS et l'élément canvas est conservée. Il n'est pas nécessaire de modifier le DOM.

La démo n'est pas animée dans Chrome ?

La version stable actuelle de Chrome (version 23) présente le bug 161699 sur crbug.com, qui empêche une animation requestAnimationFrame() de mettre à jour correctement l'arrière-plan. Ce problème a été résolu dans Chrome 25 (actuellement Canary). La démonstration devrait également fonctionner correctement dans la version actuelle de Safari.

Avantages en termes de performances

Nous parlons ici de la toile. Les animations accélérées par le matériel sont désormais pleinement opérationnelles (au moins pour les navigateurs dans lesquels cette fonctionnalité fonctionne). Et pour réitérer, il n'est pas nécessaire de modifier le DOM à partir de JS.

Utiliser WebGL comme arrière-plan

Attends une seconde. Est-ce que cela signifie que nous pouvons alimenter un arrière-plan CSS à l'aide de WebGL ? Bien sûr que oui ! WebGL n'est qu'un contexte 3D pour le canevas. Il vous suffit de remplacer "2d" par "experimental-webgl", et le tour est joué.

var gl = document.getCSSCanvasContext('experimental-webgl', 'animation', 300, 150);

Voici une preuve de concept qui contient un div avec son arrière-plan dessiné à l'aide de nuanceurs de vertex et de fragments : DÉMO

Autres approches

Il est important de noter que Mozilla dispose de -moz-element() (MDN) depuis un certain temps. Cela fait partie de la spécification CSS Image Values and Replaced Content Module Level 4 et vous permet de créer une image générée à partir de n'importe quel code HTML : vidéos, canevas, contenu DOM, etc. Toutefois, l'accès complet aux images d'instantanés du DOM pose des problèmes de sécurité. C'est principalement pour cette raison que les autres navigateurs n'ont pas adopté cette fonctionnalité.