HTML5 Canvas

(Navigation mit den Pfeiltasten.)

0 - 0

Gliederung

  1. Was ist das Canvas-Element?
  2. Wie verwende ich die Canvas-API?
  3. Harder! Better! Faster! Stronger!
  4. Ein paar Zahlen...

Los geht's!

0 - 0

Was ist das Canvas-Element?

  • Teil der HTML5 Spezifikation (Working draft)
  • ermöglicht pixelbasierte Berechnungen in einem definierten Bereichen
  • Steuerung über JavaScript APIs
  • Verwendung: Bildbearbeitung, Datenvisualisierung, Animationen, Spiele
0 - 0

Was ist das Canvas-Element?

  • low-level API: nur rudimentäre, grundlegende Funktionen
  • immediate mode rendering: kein scene graph, keine display list, nur Bearbeitung und Speicherung von Pixeldaten
  • Gegenbeispiel: Flash nutzt retained mode rendering. Hier werden keine Pixel bearbeitet, sondern Elemente einer display list (MovieClips).
  • Fazit: flexibel, aber komplex
0 - 0

Wie verwende ich die Canvas-API?

Canvas-Element in HTML erstellen (einziger Code außerhalb von JS):

                    
                        Ihr Browser unterstützt kein Canvas.
                    
                

Canvas-Element in JS referenzieren:

                    var canvas = document.getElementById("myCanvas");
                
0 - 0

Wie verwende ich die Canvas-API?

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.

0 - 0

Wie verwende ich die Canvas-API?

2D Context Koordinatensystem

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

  • Linien
  • Flächen
  • Text
  • Grafiken
0 - 0

Wie verwende ich die Canvas-API?

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)
                
Ihr Browser unterstützt kein Canvas.

(Hinweis: Rahmen mit CSS erstellt. Ein Klick zeigt das Beispiel.)

Das Zeichnen von Kreisen, Verläufen und Pfaden verhält sich ähnlich.

0 - 0

Wie verwende ich die Canvas-API?

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)
                
Ihr Browser unterstützt kein Canvas.

Text kann wie in CSS ausgezeichnet werden.

0 - 0

Wie verwende ich die Canvas-API?

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)
                
lolface Ihr Browser unterstützt kein Canvas.

(Hinweis: Das Bild muss vorher vollständig geladen sein.)

0 - 0

Wie verwende ich die Canvas-API?

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)
                
Mario Sprite Sheet Ihr Browser unterstützt kein Canvas.
0 - 0

Wie verwende ich die Canvas-API?

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();
                
Mario Sprite Sheet Ihr Browser unterstützt kein Canvas.
0 - 0

Wie verwende ich die Canvas-API?

Außerdem:

  • Transformationen: translate(x, y), scale(xScale, yScale), rotate(angle), setTransform(a,b,c,d,e,f)
  • Pixelmanipulationen: getImageData(left, top, width, height), putImageData(data, dx, dy)
  • Mehr: http://dev.w3.org/html5/2dcontext
0 - 0

Harder! Better! Faster! Stronger!

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!

0 - 0

Harder! Better! Faster! Stronger!

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.

Ihr Browser unterstützt kein Canvas. Ihr Browser unterstützt kein Canvas.

(Hinweis: Der oben genannte Code wird 1000x geloopt, um messbare Zeitangaben zu sammeln.

0 - 0

Harder! Better! Faster! Stronger!

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/)

0 - 0

Ein paar Zahlen...

Browserkompatibilität:

Welche Browser unterstützen Canvas?

(Quelle: caniuse.com, Stand: 28.10.2011)

  • native Canvas-Unterstützung bei über 60% der benutzten Browser
  • Polyfills für IE6-8: FlashCanvas (Flash), SLCanvas (Silverlight), ExplorerCanvas (VML, nativ im IE).
0 - 0

That's it!

Noch Fragen?

http://www.senaeh.de/