Rozhýbejte pozadí pomocí canvasu

Existuje několik možností, jak vytvořit ve webové aplikaci animované pozadí. Představíme vám hlavní z nich; soustředíme se na použití canvasu.

Tento text je překladem článku Canvas-driven background images, jehož autorem je Eric Bidelman a je zde zveřejněn pod licencí CC-BY-3.0.

Programujeme animované obrázky na pozadí

Máme dva hlavní přístupy pro animování obrázků na pozadí:

  1. Použít CSS sprity a JavaScriptem upravovat  background-position.
  2. Hack pomocí .toDataURL() .

První přístup funguje skvěle, pokud máte obrázky připraveny předem, ale co když je generujete ve stránce např. pomocí canvasu? Mohli bychom na canvasu použít .toDataURL() a nastavit pozadí takto vygenerovanou URL:

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

Tento přístup obsahuje dva problémy:

  1. URL s data:  přidá k velikosti obrázku ~33 %.
  2. Intenzivní práce s DOMem ( el.style).

Obě tyto metody jsou nedostačující: nelze je použít pro webové aplikace používající plynulé efekty s 60 fps.

Používáme 2d canvas jako pozadí

WebKit už roky obsahuje nestandardizované API, pomocí kterého můžeme použít canvas jako pozadí. Bohužel, pro tuhle vlastnost neexistuje žádná specifikace.

Místo nastavení obrázku jako pozadí:

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

použijeme -webkit-canvas(), kterému předáme řetězec obsahující kontext canvasu:

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

Vytvoříme 2d kontext pomocí zvláštní verze klasické metody .getContext():

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

Pozn: tato metoda se volá na objektu document, nikoliv na canvasu. Druhý argument je řetězec, který jsme použili v -webkit-canvas().

Další informace od Dave Hyatta:

Každý dokument může každému globálnímu identifikátoru přiřadit jen jeden CSS canvas. Když vytváříte kreslicí kontext, musíte také specifikovat jeho velikost. Canvas nebude smazán, pokud pro opakované volání použijete stejnou velikost. Nastavení nové velikosti odpovídá situaci, při které byste změnili velikost elementu <canvas>, a buffer canvasu bude při tom smazán.

Všechny objekty obsahující CSS canvas stejného jména, tento canvas sdílejí. To znamená (podobně jako u animovaných GIFů), že můžete vytvářet animace zobrazované synchronizovaně na několika místech najednou. Změny se automaticky propagují na všechna umístění.

Animace

Jak jste si mohli všimnout v demu výše, můžeme k ovládání animace použít requestAnimationFrame() . To je skvělé, protože po spojení  zůstává asociace mezi CSS a canvas elementem zachována. Nemusíte vůbec měnit DOM.

Nefunguje vám animace v Chromu?

Ve stabilní verzi Chrome 23 je bug bránící volání requestAnimationFrame() a aktualizaci pozadí. To bylo opraveno v Chromu 25 (Canary). Demo by mělo správně fungovat v aktuálním Safari.

Efektivita

Hovoříme tu o canvasu – ten dnes používá hardwarové akcelerované animace (alespoň v některých prohlížečích). A připomínáme, že není nutné měnit JavaScriptem DOM.

Používáme WebGL na pozadí

Ještě moment. Neznamená to, že můžeme na animovaném pozadí použít i WebGL? Přesně tak! WebGL je 3d kontextem canvasu. Stačí, když ho použijeme v „experimental-webgl“ místo „2d“ kontextu a bude to fungovat.

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

Tady je malá ukázka obsahující div s pozadím vykreslením pomocí vertextu a fragmentovaných stínů: DEMO.

Další přístupy

Měli bychom zmínit, že Mozilla již nějaký čas obsahuje -moz-element() (MDN). Jedná se o část specifikace CSS Image Values and Replaced Content Module Level 4, která vám umožní vytvořit obrázek generovaný z libovolné části HTML: videí, canvasů, DOMu… prostě z čeho chcete. Jenže umožnění takového neomezeného screenshotování je bezpečnostním rizikem. To je hlavní důvod, proč další prohlížeče tuto vlastnost neimplementovaly.

Vystudoval jsem biochemii. Vymyslel a založil Zdroják. Aktuálně ho vedu. Nejsem váš hodný tatínek, který vás bude brát za ručičku, ale zlý moderátor diskusí. Smiřte se s tím!

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Zdroj: https://www.zdrojak.cz/?p=3755