HTML5 Canvas

Los geht's!
Canvas-Element in HTML erstellen (einziger Code außerhalb von JS):
Canvas-Element in JS referenzieren:
var canvas = document.getElementById("myCanvas");
Context-Objekt abrufen:
var canvas = document.getElementById("myCanvas"); var context = canvas.getContext(contextId);
Das Context-Objekt stellt die APIs zum Zeichnen auf dem Canvas-Element bereit. Im Augenblick existiert nur ein 2D Context (contextId = "2d"), sowie ein WebGL Context (contextId = "webgl"). Letzteres ist kein Teil der HTML5 Spezifikation und wird hier nicht näher behandelt.
Der 2D Context stellt ein kartesisches Koordinatensystem dar, dessen Koordinatenursprung in der oberen linken Ecke liegt. Der x-Wert wird nach rechts größer und der y-Wert wird nach unten größer.
Der 2D Context liefert außerdem Funktionen zur Pixelmanipulation und zum Zeichnen von
Rechteck zeichnen:
var canvas = document.getElementById("canvasRectangle"); var context = canvas.getContext("2d"); context.fillStyle = "#FF0000"; // red context.fillRect(10, 10, 150, 75); // (x, y, width, height)
(Hinweis: Rahmen mit CSS erstellt. Ein Klick zeigt das Beispiel.)
Das Zeichnen von Kreisen, Verläufen und Pfaden verhält sich ähnlich.
Text zeichnen:
var canvas = document.getElementById("canvasText"); var context = canvas.getContext("2d"); context.font = "bold 30px sans-serif"; // font style context.fillText("Siebzehn!", 17, 107); // (string, x, y)
Text kann wie in CSS ausgezeichnet werden.
Bilder zeichnen:
var canvas = document.getElementById("canvasImage"); var context = canvas.getContext("2d"); var image = document.getElementById("testImage"); // reference to image context.drawImage(image, 70, 20, 150, 150); // (img, x, y, width, height)
(Hinweis: Das Bild muss vorher vollständig geladen sein.)
Bilderausschnitte zeichnen:
var canvas = document.getElementById("canvasImageTile"); var context = canvas.getContext("2d"); var image = document.getElementById("marioSprite"); context.drawImage(image, 0, 0, 55, 72, // (img, source-x, source-y, source-width, source-height, 120, 60, 55, 72); // x, y, width, height)
Sprite Sheet Animationen:
var i = 0; var loop = function() { context.clearRect(0, 0, canvas.width, canvas.height); // clear old image context.drawImage(image, 55 * i, 0, 55, 72, 120, 60, 55, 72); i++; if(i >= 5) i = 0; setTimeout(loop, 90); }; loop();
Außerdem:
Bessere Loops mit requestAnimationFrame:
var loop = function() { requestAnimFrame(loop); // do stuff HERE }; window.requestAnimFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60); }; // 16 ms = ~60 fps })();
(Quelle: http://paulirish.com/2011/requestanimationframe-for-smart-animating/)
Renderloop vom Browser verwaltet! Synchronisiert mit CSS3 Animationen. Wird nur ausgeführt, wenn Seite sichtbar: bessere GPU+CPU Ausnutzung, bessere Akkulaufzeit! Mehr Performance!
Off screen Canvas:
// bad: rotate image in every frame context.save(); context.rotate(angle); context.drawImage(image, 0, 0); context.restore(); // good: rotate image once and draw it to an off screen canvas // redraw the off screen canvas in every frame context.drawImage(offScreenCanvasWithRotatedImage, 0, 0);
Anstatt bspw. ein Bild mit dem Winkel α mehrmals auf ein Canvas zu zeichnen ist es performanter das Bild auf einem nicht sichtbaren Canvas mit diesem Winkel zu zeichnen und dann das nicht sichtbare Canvas-Element auf ein sichtbares Canvas-Element zu zeichnen.
(Hinweis: Der oben genannte Code wird 1000x geloopt, um messbare Zeitangaben zu sammeln.
Zeichnen auf Sub-Pixeln vermeiden!
// bad: using sub pixel context.drawImage(image, 0.5, 0.5); // good: avoid using sub pixel context.drawImage(image, Math.round(0.5), Math.round(0.5));
Zeichnen auf Sub-Pixeln löst Anti-Aliasing aus. Performancekiller!
(Quelle: http://sebleedelisle.com/2011/02/html5-canvas-sprite-optimisation/)
Browserkompatibilität:
(Quelle: caniuse.com, Stand: 28.10.2011)
Noch Fragen?