Het HTML 5 canvas is een enorm krachtig element dat dynamische gegenereerde graphics en animaties mogelijk maakt in de browser (zonder plugins). Het canvas heeft erg veel mogelijkheden, maar ook zo zijn beperkingen. In sommige gevallen kan het pre-renderen van graphics een enorme performance winst opleveren.

Canvas animatie
Het is alweer een aantal jaren geleden dat ik een blog serie heb geschreven over het canvas en de mogelijkheden om dingen te animeren op het canvas. Deze blogs kun je hier terug vinden.
Deel 1
Deel 2
Deel 3
 
De zeer korte samenvatting: Animeren op het canvas betekent:
- Achtergrond tekenen,
- de te animeren objecten tekenen,
- berekenen waar de objecten de volgende keer getekend moeten worden
- paar milliseconden wachten,
- herhaal bovenstaande 
 
Het lijkt omslachtig, maar werkt verbazingwekkend goed. Het animeren van duizenden objecten tegelijker tijd hoeft geen issue te zijn. Het probleem omstaat echter wanneer het te tekenen object (of objecten) complexe tekenacties (rendering) vereist. Hierbij kun je denken aan een vliegtuigje met veel vormen, kleuren en lijnen, maar andere voorbeelden zijn ook zaken als teksten of schaduwen. Deze lijken op het eerste oog wellicht niet zo complex, maar voor de processor is een tekst een verzameling van lijnen en curves en voor een schaduw moet het effect voor elke pixel berekend worden.

Een kant en klare afbeelding tekenen is een stuk minder complex. Een afbeelding is feitelijk een array van pixels, net als het canvas zelf. Een afbeelding tekenen op het canvas is daarmee niet veel meer dan het samenvoegen van 2 arrays.

Het Prerenderen
Het feit dat afbeeldingen (pixel arrays) tekenen een eenvoudigere taak is voor het Canvas kunnen we gebruiken om de performance van het canvas te verbeteren. In het geheugen kun je meerdere canvassen aanmaken zonder dat deze op het scherm getoond hoeven worden.

prerenderCanvas = document.createElement('canvas');
prerenderCanvas.width = 110;
prerenderCanvas.height = 30;
prerenderContext = prerenderCanvas.getContext('2d');
 
Op dit extra canvas (dat ik hier "prerenderCanvas” genoemd heb) kun je vervolgens je complexe teken actie uitvoeren. Wanneer je dan de animatie uitvoert, voer je niet tekens de complexe teken actie uit, maar teken je de inhoud van het pre-render canvas op het zichtbare "hoofd” canvas.

context.drawImage(prerenderCanvas, posX, posY);

Voorbeeld
Hieronder kun je een voorbeeld zien. Het licht blauwe vlak is een HTML 5 Canvas. Wanneer je op de start knop drukt, zullen er 100 teksten gaan animeren op het scherm. Het zijn teksten met een omlijning en een schaduw. Je zult dan ook zien dat de performance niet lekker is. Door middel van de knop "Turn prerender ON” kun je overschakelen op de versie die gebruik maakt van pre-rendering. Eerst wordt de tekst op een tweede canvas in het geheugen getekend en vervolgens wordt dit extra canvas gebruikt om te animeren.Het voorbeeld is zo geschreven dat het effect in Internet Explorer het meest duidelijk is. Mocht je een andere browser gebruiken dan kan het zijn dat je andere effecten te zien krijgt.

Naast de browser, zijn ook de CPU en GPU van je computer zijn erg bepalend voor het effect. Dus ondanks dat het effect wellicht niet duidelijk zichtbaar is in dit voorbeeld, is het pre-renderen in diverse situaties een goede oplossing. Mocht je issues hebben, bekijk dan zeker of dit je kan helpen.