Canvasgestuurde achtergrondafbeeldingen

Achtergrondafbeeldingen programmatisch animeren

Er zijn twee belangrijke manieren waarop mensen achtergrondafbeeldingen animeren :

  1. Gebruik CSS-sprites om een background-position in JS bij te werken.
  2. Hacken met .toDataURL() .

De eerste werkt prima als je de afbeelding van tevoren hebt, maar wat als je bronprogrammatisch gegenereerd moet worden, bijvoorbeeld door een <canvas> ? De oplossing voor #1 is om .toDataURL() op het canvas te gebruiken en de achtergrond in te stellen op de gegenereerde URL:

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

Er zijn twee problemen hiermee:

  1. data: URL's voegen een overhead van ~33% toe aan de resulterende afbeelding.
  2. Een hoop DOM-ontroerend ( el.style ).

Beide methoden zijn inefficiënt: onaanvaardbaar voor een altijd zijdezachte web-app van 60 fps.

2D-canvas als achtergrond gebruiken

Canvas als achtergronddemo
DEMO

Het blijkt dat er een niet-standaard API is die WebKit al jaren heeft en die canvas als bron voor een achtergrond kan gebruiken. Helaas zijn er echter geen gepubliceerde specificaties voor deze functie .

Ten eerste, in plaats van een URL voor de achterkant op te geven:

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

gebruik -webkit-canvas() , verwijzend naar een tekenreeks-ID naar een canvascontext:

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

Vervolgens moeten we de 2D-context creëren met een speciale versie van .getContext() :

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

Meer informatie van Dave Hyatt:

Animaties

Zoals u in de demo kunt zien, kunnen we requestAnimationFrame() opnieuw gebruiken om een ​​animatie aan te sturen. Dit is geweldig, want zodra de zaken zijn aangesloten, blijft de associatie tussen CSS en het canvaselement behouden . Het is niet nodig om met de DOM te spelen.

Demo niet geanimeerd in Chrome?

Het huidige stabiele kanaal van Chrome (versie 23) heeft crbug.com/161699 , wat voorkomt dat een requestAnimationFrame() animatie de achtergrond correct bijwerkt. Dit is opgelost in Chrome 25 (momenteel Canary). De demo zou ook goed moeten werken in de huidige Safari.

Prestatievoordelen

We hebben het hier over canvas. Hardwareversnelde animaties zijn nu volledig beschikbaar (althans voor de browsers waarin deze functie werkt). En om het nog maar eens te herhalen: het is niet nodig om de DOM van JS te misbruiken .

Gebruik webgl als achtergrond

Wacht even. Betekent dit dat we een CSS-achtergrond kunnen aandrijven met behulp van webgl? Natuurlijk wel! WebGL is slechts een 3D-context voor canvas. Wissel gewoon "experimental-webgl" in in plaats van "2d", en voila.

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

Hier is een proof of concept dat een div bevat waarvan de achtergrond is getekend met behulp van vertex- en fragment-shaders: DEMO

Andere benaderingen

Het is vermeldenswaard dat Mozilla al geruime tijd -moz-element() ( MDN ) heeft. Dit maakt deel uit van de CSS Image Values ​​and Replaced Content Module Level 4 -specificatie en stelt u in staat een afbeelding te maken die is gegenereerd op basis van willekeurige HTML: video's, canvas, DOM-inhoud,... noem maar op. Er zijn echter beveiligingsproblemen bij het hebben van volledige toegang tot momentopnamen van de DOM. Dit is vooral de reden waarom andere browsers deze functie niet hebben overgenomen.