Immagini di sfondo create con canvas

Eric Bidelman

Animazione programmatica delle immagini di sfondo

Esistono due modi principali per animare le immagini di sfondo:

  1. Utilizza sprite CSS per aggiornare un elemento background-position in JS .
  2. Trucchi con .toDataURL() .

La prima è molto utile se hai l'immagine in anticipo, ma cosa succede se la sorgente deve essere generata in modo programmatico, ad esempio da un <canvas>? La soluzione n. 1 è utilizzare .toDataURL() sul canvas e impostare lo sfondo sull'URL generato:

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

Questo processo presenta due problemi:

  1. data: URL aggiungono un overhead per le dimensioni dell'immagine risultante di circa il 33%.
  2. Una tonnellata di tocchi DOM (el.style).

Entrambi i metodi non sono efficaci ed è inaccettabile per un'app web a 60 fps sempre fluida.

Utilizzo di canvas 2D come sfondo

Canvas come demo di sfondo
DEMO

Abbiamo scoperto che esiste un'API non standard che WebKit utilizza da anni che può utilizzare la canvas come sorgente per uno sfondo. Purtroppo non sono state pubblicate specifiche per questa funzionalità.

Innanzitutto, invece di specificare un URL per il retro:

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

utilizza -webkit-canvas(), facendo riferimento a un identificatore stringa e a un contesto canvas:

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

A questo punto, dobbiamo creare il contesto 2D con una versione speciale di .getContext():

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

Ulteriori informazioni da Dave Hyatt:

Animazioni

Come mostrato nella demo, possiamo riutilizzare requestAnimationFrame() per generare un'animazione. Questo è ottimo, perché una volta collegati gli elementi, l'associazione tra CSS e l'elemento canvas viene mantenuta. Non è necessario giocherellare con il DOM.

La demo non è animata in Chrome?

L'attuale canale stabile di Chrome (versione 23) ha crbug.com/161699, che impedisce a un'animazione requestAnimationFrame() di aggiornare correttamente lo sfondo. Questo problema è stato risolto in Chrome 25 (attualmente canary). Anche la demo dovrebbe funzionare correttamente nel Safari attuale.

Vantaggi delle prestazioni

Stiamo parlando della tela. Le animazioni con accelerazione hardware ora sono completamente attive (almeno per i browser in cui viene usata questa funzionalità). Solo per ribadire, non è necessario molestare il DOM da JS.

Utilizzo di webgl come sfondo

Aspetta un secondo. Questo significa che possiamo potenziare uno sfondo CSS utilizzando webgl? Certo che sì! WebGL è semplicemente un contesto 3D per la stampa su tela. È sufficiente sostituire "experimental-webgl" anziché "2d" e il gioco è fatto.

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

Di seguito è riportato un proof of concept che contiene un elemento div con il suo sfondo disegnato utilizzando gli Shader di vertici e frammenti: DEMO

Altri approcci

Vale la pena notare che Mozilla ha -moz-element() (MDN) da un po' di tempo. Fa parte delle specifiche CSS Image Values andminos Content Module Level 4 e ti consente di creare un'immagine generata da codice HTML arbitrario: video, canvas, contenuti DOM e così via. Tuttavia, la sicurezza dell'accesso completo alle immagini istantanee del DOM comporta problemi di sicurezza. Questo è principalmente il motivo per cui altri browser non hanno adottato tale funzionalità.