Canvasgestuurde achtergrondafbeeldingen

Achtergrondafbeeldingen programmatisch animeren

Er zijn twee belangrijke manieren waarop mensen achtergrondafbeeldingen animeren :

  1. Gebruik CSS-sprites om de background-position in JavaScript bij te werken.
  2. Trucs met .toDataURL() .

De eerste methode werkt prima als je de afbeelding van tevoren hebt, maar wat als je bron programmatisch gegenereerd moet worden, bijvoorbeeld door een <canvas> ? De oplossing voor punt 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 + ')';
}

Hier zijn twee problemen mee:

  1. data: URL's voegen ongeveer 33% toe aan de bestandsgrootte van de resulterende afbeelding.
  2. Heel veel DOM-aanrakingen ( el.style ).

Beide methoden zijn inefficiënt: onacceptabel voor een webapplicatie die altijd vloeiend op 60 fps moet draaien.

Het 2D-canvas gebruiken als achtergrond

Canvas als achtergronddemonstratie
DEMO

Het blijkt dat WebKit al jaren een niet-standaard API heeft waarmee canvas als achtergrond kan worden gebruikt. Helaas is er echter geen gepubliceerde specificatie voor deze functie .

Ten eerste, in plaats van een URL voor de back-up op te geven:

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

Gebruik -webkit-canvas() en verwijs naar een canvascontext met behulp van een string-identificatie:

.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 in de demo te zien is, kunnen we requestAnimationFrame() hergebruiken om een ​​animatie aan te sturen. Dit is geweldig, want zodra alles is gekoppeld, blijft de associatie tussen CSS en het canvas-element behouden . Er is geen noodzaak om met de DOM te rommelen.

Wordt de demo niet geanimeerd in Chrome?

De huidige stabiele versie van Chrome (versie 23) bevat bug crbug.com/161699 , waardoor een requestAnimationFrame() -animatie de achtergrond niet correct bijwerkt. Dit is verholpen in Chrome 25 (momenteel Canary). De demo zou ook goed moeten werken in de huidige versie van Safari.

Prestatievoordelen

We hebben het hier over canvas. Hardwareversnelde animaties zijn nu volledig operationeel (althans voor de browsers waarin deze functie werkt). En om het nogmaals te benadrukken: het is niet nodig om de DOM vanuit JavaScript te manipuleren .

WebGL gebruiken als achtergrond

Wacht even. Betekent dit dat we een CSS-achtergrond kunnen aansturen met WebGL? Natuurlijk! WebGL is slechts een 3D-context voor canvas. Vervang "2d" door "experimental-webgl" en klaar is Kees.

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

Hier is een proof of concept met een div waarvan de achtergrond is getekend met behulp van vertex- en fragmentshaders: DEMO

Andere benaderingen

Het is belangrijk om te weten dat Mozilla al geruime tijd de functie -moz-element() ( MDN ) heeft. Deze functie maakt deel uit van de CSS Image Values ​​and Replaced Content Module Level 4 -specificatie en stelt je in staat om een ​​afbeelding te genereren op basis van willekeurige HTML: video's, canvas, DOM-content, enzovoort. Er zijn echter beveiligingsrisico's verbonden aan volledige toegang tot momentopnamen van de DOM. Dit is de belangrijkste reden waarom andere browsers deze functie niet hebben overgenomen.