Das Canvas Element

Das Wort "Canvas" kommt aus dem englischen und bedeutet "Leinwand". Mit dieser Übersetzung können wir uns bereits ohne Kenntnisse von HTML5 und dem Thema Grafik im Web vorstellen, was es damit auf sich hat. Wir können mit diesem Element Grafiken auf eine Fläche malen, sie bearbeiten, skalieren, verändern oder sogar animieren.

Das <canvas></canvas> Element muss im HTML-DOM eingebunden werden und sollte im body Bereich stehen, damit es sichtbar ist.

  • Html
  • Ergebnis
<html> <head></head> <body> <canvas style="border: 1px solid red;"></canvas> </body> </html>

Standardmäßig definiert der Browser dieses Element als inline und nimmt eine Breite und Höhe von 300px zu 150px.

The canvas element has two attributes to control the size of the element's bitmap: width and height. These attributes, when specified, must have values that are valid non-negative integers. [...] The width attribute defaults to 300, and the height attribute defaults to 150.

Das Canvas Element hat zwei Attribute, um die Größe der Bitmap des Elements zu kontrollieren. Wenn diese Attribute gesetzt sind, müssen sie valide positive Integerwerte sein. [...] Der Standardwert für die Breite ist 300 und für die Höhe ist 150.

Dennoch sollten wir die Größe unseres Elements mithilfe der Attribute width="" und height="" setzen:

  • Html
  • Ergebnis
<html> <head></head> <body> <canvas width="600" height="200" style="border: 1px solid red;"></canvas> </body> </html>

Canvas Fallback

Unter dem Canvas Fallback versteht man ein Szenario, das greift, wenn der Browser das <canvas></canvas> Element nicht anzeigen kann. Dafür bietet das Element selbst eine einfache Lösung:

  • Html
  • Ergebnis
<html> <head></head> <body> <canvas width="600" height="200" style="border: 1px solid red;"> Dieser Text wird angezeigt, falls das Canvas nicht angezeigt werden kann </canvas> </body> </html>

Mithilfe des Warntextes können wir den Benutzer darauf hinweisen, dass an dieser Stelle der Inhalt nicht angezeigt werden kann.

Der Canvas Kontext

Um nun tatsächlich eine grafische Ausgabe auf dem Bildschirm zu erzeugen, benötigen wir allerdings Javascript. Mithilfe dieser Sprache können wir einen context erzeugen. Dabei handelt es sich um ein Objekt, mit Funktionen und Variablen, mit denen wir das <canvas></canvas> Element bemalen können.

Den Javascript Code können wir unter unserem Canvas mithilfe des <script></script> Elements einbinden:

  • Html
  • Javascript
  • Ergebnis
<html> <head></head> <body> <canvas id="canvas_id" width="600" height="200"></canvas> <script> // Javascript Code sollte hier stehen </script> </body> </html>
var Canvas = document.getElementById("canvas_id"); var Context = Canvas.getContext("2d"); Context.fillStyle = "#000"; Context.fillRect( 0, 0, 600, 200 );

Im obigen Beispiel wird mithilfe von Javascript eine Variable mit dem Namen "Canvas" erstellt. Mithilfe der Funktion getElementById, die wir von dem Object document aufrufen müssen, können wir unser Canvas mithilfe der ID finden.

Jetzt besorgen wir uns den Kontext von unserem Canvas-Objekt. Dafür steht uns die Funktion getContext( ContextTyp, ContextAttribute ) zur Verfügung, welche zwei Parameter annimmt. Mit dem Wert 2d geben wir an, dass wir einen zweidimensionalen RenderingContext haben wollen. Den zweiten Parameter setzen wir nicht, um so die Standardeinstellungen zu bekommen.

Anschließend können wir mit unserer Context-Variable unser gesamtes Canvas schwarz färben. Dazu haben wir die Funktionen fillStyle() und fillRect() benutzt, die später näher erläutert werden.

Wichtig ist hierbei, dass jegliche Anweisungen immer über das Context-Objekt getätigt werden.

Das Problem mit CSS

Setzt man die Elementgröße mit CSS, kommt es ohne weiteres oft zu Problemen. Das liegt daran, dass die Werte der Attribute nicht direkt die Größe des Elements festlegen, sondern die Anzahl an Pixeln, die zum rendern benutzt werden können. Der Browser passt anschließend die Elementgröße dem gezeichneten an, wenn dafür keine CSS Regeln gesetzt wurden.

  • Html
  • Javascript
  • Ergebnis
<html> <head></head> <body> <canvas id="canvas_id" width="32" height="32" style="border: 1px solid red;"></canvas> <script> // Javascript Code sollte hier stehen </script> </body> </html>
var Canvas = document.getElementById( "canvas_id" ); var Context = Canvas.getContext( "2d" ); Context.beginPath(); Context.arc( Canvas.width>>1, Canvas.height>>1, 15, 0, 2 * Math.PI, false ); Context.fillStyle = "red"; Context.fill(); Context.stroke();

Setzen wir die Attribute also auf 32x32, haben wir insgesamt 1024 Pixel, mit denen wir arbeiten können. Der Browser skaliert unser <canvas></canvas> Element dementsprechend auf 32x32 Pixel, damit der gesamte Inhalt des Elements angezeigt werden kann. Im obigen Beispiel zeichnen wir einen Kreis in der Mitte des Canvas mit einem Radius von 15 Pixeln, sodass wir unsere Fläche komplett ausfüllen.

Würden wir nun die Größe mithilfe von CSS auf das vier-fache (128x128) setzen, müsste der Browser unseren grafischen Inhalt auf diese Größe skalieren. Dies macht er in der Regel mit dem Interpolationsverfahren, dass hier nicht näher beschrieben werden soll. Allerdings sollte man wissen, dass er die Farbe anderer Pixel berechnen muss, da wir ja bei 128x128 insgesamt 16.384 Pixel benötigen. Je größer der Unterschied zwischen den Ausgangs- und Zielpixeln, desto schwerer ist es, die Interpolation durchzuführen und das Bild wirkt verschwommener.

  • Html
  • Javascript
  • Ergebnis
<html> <head></head> <body> <canvas id="canvas_id" width="32" height="32" style="border: 1px solid red; width: 128px; height: 128px;"></canvas> <script> // Javascript Code sollte hier stehen </script> </body> </html>
var Canvas = document.getElementById( "canvas_id" ); var Context = Canvas.getContext( "2d" ); Context.beginPath(); Context.arc( Canvas.width>>1, Canvas.height>>1, 15, 0, 2 * Math.PI, false ); Context.fillStyle = "red"; Context.fill(); Context.stroke();

Ein richtiger Ansatz wäre es, die Attribute des <canvas></canvas> Elements auf die CSS-Werte zu setzen. Canvas.width und Canvas.height können wir dann für die Kreiszeichnung benutzen:

  • Html
  • Javascript
  • Ergebnis
<html> <head></head> <body> <canvas id="canvas_id" width="32" height="32" style="border: 1px solid red; width: 128px; height: 128px;"></canvas> <script> // Javascript Code sollte hier stehen </script> </body> </html>
var Canvas = document.getElementById( "canvas_id" ); Canvas.width = parseInt(Canvas.style.width); Canvas.height = parseInt(Canvas.style.height); var Context = Canvas.getContext( "2d" ); Context.beginPath(); Context.arc( Canvas.width>>1, Canvas.height>>1, Math.min( Canvas.width, Canvas.height )>>1, 0, 2 * Math.PI, false ); Context.fillStyle = "red"; Context.fill(); Context.stroke();

Beim obigen Beispiel können wir die Größe unseres Canvas mithilfe von CSS auf jede beliebige Größe setzen. Da der kleinere der beiden Seitenwerte als Radius genutzt wird, laufen wir auch nicht dem Problem aus, dass der Kreis für eine Achse zu groß sein könnte. Zusätzlich könnten wir die Attribute beim Element jetzt weglassen, da wir sie per Javascript setzen.