2D-Grafiken erstellen

2-Dimensionale Grafiken werden mit JavaScript entweder in der Canvas-API oder als SVG erstellt.

Über die Canvas-API kann über eine definierte Fläche gezeichnet werden. SVG bedeutet Scalable Vector Graphics und moderne Browser verstehen auch diese Grafiken. Das Element <canvas> stellt die Zeichenfläche dar, auf der wir mit JavaScript zugreifen können und mit Hilfe der Canvas API zeichnen können. Um die Größe der Zeichenfläche zu definieren, verwenden wir die Attribute "width" für breite und "height" für die Höhe, wenn keine Attribute angegeben sind, dann ist die Standarteinstellung 300 x 150px. Es bietet sich an, das Canvas Element eine Id zuzuweisen, um mit JavaScript auf die Id der Zeichenfläche zugreifen zu können.

Canvas-Element in HTML erstellen

<canvas id="canvas" width="500" height="300"></canvas>

Um die Zeichenfläche sehen zu können, verpassen wir Ihr erst einmal einen Rahmen in der CSS-Datei.

Rahmen definieren

#canvas {
 border: 1px solid black;
}

Der Rendering-Kontext

Das <canvas>-Element stellt mehrere Rendering-Kontexte zur Verfügung. Darüber lässt sich der Inhalt der Zeichenfläche manipulieren. Die Methode "getContext()" erwartet den Parameter "2d" für ein 2D-Rendering-Kontext, oder "webgl" für ein 3D-Rendering-Kontext.

Kontext definieren

let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');

Beim Überliefern des Parameters "2d" liefert die Methode "getContext()" ein Objekt vom Typ "CanvasRenderingContext2D" zurück. Beim Überliefern des Parameters "webgl" liefert uns die Methode "getContext()" ein Objekt vom Typ "WebGLRenderingContext" zurück. Bei der Unterstützung von "webgl2" erhalten wir ein Objekt vom Typ "WebGL2RenderingContext". Browser, die bereits die zweite Version von "webgl" unterstützen, übergeben den Parameter "webgl2". Der 2D-Kontext besitzt ein zweidimensionales Koordinatensystem, in dem wir pixelgenau zeichnen können, indem wir uns nach den X und Y Koordinaten richten. Das Koordinatensystem beginnt mit 0/0 in der linken oberen Ecke. Grafikelemente wie Kreise oder Rechtecke werden relativ zur Ursprungskoordinate auf die Zeichenfläche gezeichnet.


Rechtecke Zeichnen

Der Typ "CanvasRenderingContext2D" bietet 3 verschiedenen Methoden, um Rechtecke zu zeichnen. Die Methode "strokeRect()" erstellt den Umriss eines Rechtecks. Um den Rand sichtbar zu machen, muss im Vorhinein eine Farbe für den Rand definiert werden.

Rand definieren und anzeigen lassen

function zeichnen() {
 context.strokeStyle = 'rgb(0,250,300)';
 context.strokeRect(50, 50, 400, 200);
}
zeichnen();

Innerhalb der Zeichenfläche ist jetzt ein rechteckiger Rahmen zu erkennen. Mit der Methode "fillRect()" erstellen wir ein Rechteck, welches mit einer vorher definierten Hintergrundfarbe gefüllt wird.

Rechteck mit Farbe füllen

context.fillStyle = 'rgb(0,250,300)';
context.fillRect(100, 100, 300, 100);

In der Zeichenfläche ist jetzt auch ein gefülltes Rechteck zu erkennen. Um etwas von dem gefüllten Rechteck zu entfernen, können wir einfach mit der Methode "clearRect()" ein Rechteck aus einer gefüllten Fläche gelöscht.

Rechteck entfernen

context.clearRect(120, 120, 260, 60);

Das Endergebnis sollte in etwa so aussehen.

Rechtecke im Browser

Alle 3 Methoden haben dieselben 4 Parameter, die beiden ersten Parameter setzen den Startpunkt fest und die beiden letzten Parameter bestimmen die Größe des Rechtecks. Die Farben, die für "fillRect()" und "strokeRect()" definiert sind, gelten auch für alle anderen darauf folgenden "fillRect()" oder "strokeRect()" aufrufe, bis ein anderer Wert angewiesen wird. Rechtecke sind die einzige geometrische Grundform, bei der wir mit solchen Methoden arbeiten können, alle anderen Formen wie Dreiecke oder Kreise müssen über sogenannte Pfade gezeichnet werden.


Pfade verwenden

Wenn wir uns mit der Canvas-API beschäftigen, dann sind Pfade eine Aneinanderreihung von Koordinaten, die durch Linien miteinander verbunden sind. Diese Linien können gerade sein, das bedeutet auch, dass sie ebenso gebogen sein können.


Gerade Linien zeichnen

Um eine einfache, gerade Linie zu zeichnen, müssen wir einen Startpunkt festlegen, an dem wir anfangen, die Linie zu zeichnen. Im Anschluss darauf setzen wir einen Endpunkt fest und geben der Linie etwas Farbe.

Linie zeichnen

function zeichnen() {
 context.beginPath();
 context.moveTo(200, 50);
 context.lineTo(100, 150);
 context.stroke();
}

Mit "beginPath()" beginnen wir den Pfad zu erstellen, mit "moveTo()" setzen wir die Startkoordinaten fest. Mit "lineTo()" legen wir die Zielkoordinaten fest, und mit "stroke()" färben wir das Ganze etwas ein. Wenn der Methode "stroke()" kein Wert gegeben wird, dann wird schwarz als Standardfarbe verwendet. Den Vorgang kann man sich so vorstellen. Mit "beginPath()" sagen wir, dass wir etwas Zeichnen möchten. Mit "moveTo()" setzen wir den Stift an bestimmten Koordinaten an. Dann ziehen wir eine Linie bis zu den Koordinaten der Methode "lineTo()". Am Ende wird diese Zeichnung eingefärbt. Wenn wir jetzt mehr als nur eine Linie Zeichnen wollen, dann müssen wir den Stift ja nicht gleich bei "lineTo()" absetzen, sondern können direkt an diesem Punkt weiter zeichnen. Wir erweitern die Funktion, um ein paar Anweisungen.

Weitere Linien zeichnen

context.lineTo(200, 250);
context.lineTo(250, 250);
context.lineTo(200, 200);
context.lineTo(350, 200);
context.lineTo(400, 250);
context.lineTo(400, 50);
context.lineTo(350, 100);
context.lineTo(200, 100);
context.lineTo(250, 50);

Nun haben wir eine Zeichnung mit ein paar Linien, die zwar kein Kunstwerk ergeben, aber gut Demonstrieren, wie man mit JavaScript Zeichnen kann. Um aus den Linien eine Fläche zu machen, also eine letzte Linie zum Anfangspunkt zu ziehen, können wir ganz einfach die Methode "closePath()" verwenden.

Gesamte Grafik aus Linie zeichnen

function zeichnen() {
 context.beginPath();
 context.moveTo(200, 50);
 context.lineTo(100, 150);
 context.lineTo(200, 250);
 context.lineTo(250, 250);
 context.lineTo(200, 200);
 context.lineTo(350, 200);
 context.lineTo(400, 250);
 context.lineTo(400, 50);
 context.lineTo(350, 100);
 context.lineTo(200, 100);
 context.lineTo(250, 50);
 context.closePath();
 context.stroke();
}
zeichnen();
Pfeil im Browser zeichnen

Quadratische Kurven zeichnen

Betrachten wir doch mal ein paar Möglichkeiten, um gebogene Linien zu zeichnen. Die Methode "quadraticCurveTo()" bietet die Möglichkeit, eine quadratische Kurve zu zeichnen. Eine quadratische Kurve ist wie ein Dreieck, bei dem eine gerade Linie von A nach B gezogen wird und dann in Richtung Kontrollpunkt C gezogen wird. Zur Demonstration können wir mit 2 Linien ein Kreuz an den Kontrollpunkt bei 50, 100 einzeichnen.

Kontrollpunkt einzeichnen

function zeichnen() {
 context.beginPath();
 context.moveTo(50, 90);
 context.lineTo(50, 110);
 context.stroke();
 context.beginPath();
 context.moveTo(40, 100);
 context.lineTo(60, 100);
 context.stroke();
}
zeichnen();

Beginnen wir mit dem Zeichnen der quadratischen Kurve.

Quadratische Kurve zeichnen

context.moveTo(100, 100);
context.quadraticCurveTo(50, 100, 50, 150);
context.stroke();
Quadratische Kurve im Browser zeichnen

Die Methode "moveTo()" bekommt wieder die Koordinaten, an denen wir mit dem virtuellen Stift ansetzen. Die Methode "quadratCurveTo()" bekommt 4 Parameter in der Reihenfolge: X-Koordinate vom Kontrollpunkt, Y-Koordinate vom Kontrollpunkt, X-Koordinate vom Zielpunkt und Y-Koordinate vom Zielpunkt.


Bézierkurven zeichnen

Kurven mit 2 Kontrollpunkten werden Bézierkurven genannt. Bei der Zeichnung dieser Kurven entsteht eine geschwungene Linie, die auch als S-Kurve bezeichnet werden könnte.

Kontrollpunkte und Kurve einzeichnen

function zeichnen() {
 // Kontrollpunkt 1 bei 100, 50
 context.beginPath();
 context.moveTo(100, 40);
 context.lineTo(100, 60);
 context.stroke();
 context.beginPath();
 context.moveTo(90, 50);
 context.lineTo(110, 50);
 context.stroke();
 // Kontrollpunkt 2 bei 300, 250
 context.beginPath();
 context.moveTo(300, 240);
 context.lineTo(300, 260);
 context.stroke();
 context.beginPath();
 context.moveTo(290, 250);
 context.lineTo(310, 250);
 context.stroke();
 // Bézierkurve
 context.moveTo(300, 50);
 context.bezierCurveTo(100, 50, 300, 250, 100, 250);
 context.stroke();
}
zeichnen();
Bezierkurve im Browser zeichnen

Die Methode "bezierCurveTo()" erwarten 6 Parameter, wobei die ersten beiden für die Koordinaten des ersten Kontrollpunktes stehen. Die Parameter an dritter und vierter Stelle stehen für die Koordinaten des zweiten Kontrollpunktes. Die Parameter an fünfter und sechster Stelle stehen für die Zielkoordinaten, wo die Linie hingezeichnet werden soll.


Bögen und Kreise zeichnen

Bei dem zeichnen von Bögen und Kreisen bieten sich gleich 2 Methoden an. "arc()" und "arcTo()", als Erstes betrachten wir die Methode "arcTo()".


arcTo()

Die Methode erwartet 5 Parameter, die ersten beiden Parameter sind die Koordinaten für den Kontrollpunkt. Die beiden nächsten Parameter stehen für den Zielpunkt der Kurve. Der fünfte Parameter bestimmt, welchen Radius der Bogen haben soll.

Bogen mir arcTo() zeichnen

function zeichnen() {
 context.moveTo(50, 100);
 context.lineTo(100, 100);
 context.arcTo(200, 100, 200, 200, 100);
 context.lineTo(200, 250);
 context.lineTo(250, 250);
 context.lineTo(250, 200);
 context.arcTo(250, 100, 350, 100, 100);
 context.lineTo(400, 100);
 context.stroke();
}
zeichnen();
Mit arcTo im Browser zeichnen

Neben der Methode "arcTo()" gibt es noch die Methode "arc()".


arc()

Bei "arc()" werden 6 Parameter benötigt. Die ersten beiden Parameter geben die Koordinaten für das Bogenzentrum an. Darauf folgt der Radius des Bogens sowie der Startwinkel und der Endwinkel des Bogens. Als letzten Parameter geben wir als booleschen Wert an, ob der Bogen im Uhrzeigersinn (false) oder gegen den Uhrzeigersinn (true) gezeichnet werden soll.

Bogen mit arc() zeichnen

function zeichnen() {
 context.arc(250, 150, 100, 0, 3*Math.PI/2, false);
 context.stroke();
}
zeichnen();

Das Ergebnis ist ein Kreis, der im ersten Viertel offenbleibt.

Mit arc im Browser zeichnen

Texte zeichnen

Das Zeichnen von Texten ist über die Methode "fillText()" und "strokeText()" möglich. Beide Methoden erwarten als ersten Parameter den Text, als zweiten und dritten Parameter erwarten die Methoden die Koordinaten, um den Text zu platzieren.

Text zeichnen

function zeichnen() {
 context.font = '60px serif';
 context.fillText('Text gefüllt', 20, 100);
 context.strokeText('Text umrandet', 120, 200);
}
zeichnen();
Text im Browser zeichnen

Zusätzlich lässt sich über verschiedene Eigenschaften noch die Ausrichtung Schriftgröße, Schriftfarbe usw. einstellen.


Weiteres

Anstelle von einzelnen Farben können wir auch hier mit Farbverläufen arbeiten. Dabei unterscheiden wir zwischen lineare Farbverläufe und radiale Farbverläufe. Zudem können wir noch Transformationen wie das skalieren, verschieben oder rotieren anwenden. Zum Schluss können wir auch Animationen auf die Elemente anwenden.


Vektorgrafiken einbinden

Scalable Vector Graphics oder kurz SVG. Die Alternative zur Canvas API. Bei SVG handelt es sich um ein XML basierte Auszeichnungssprache, um zweidimensionale Vektorgrafiken zu definieren. Das bedeutet, dass wir die Grafiken mithilfe von Elementen erstellen.

<Element> Ergebnis
<rect> erzeugt ein Rechteck
<circle> erzeugt ein Kreis
<ellipse> erzeugt eine Ellipse
<polyline> erzeugt eine Linie mit Zwischenpunkten
<polygon> erzeugt ein Polygon
<path> Pfad
<g> Gruppe von Grafikelementen
<text> Textinhalt
<a> Hyperlink
<image> externe Bilder
<linearGradient> linearer Farbverlauf
<radialGradient> radialer farbverlauf

Das manuelle Erstellen der Grafik über die Elemente ist sehr mühsam, daher ist es ratsam, die Grafik in entsprechenden Programmen zu erstellen und dann zu exportieren. Das Einbinden der SVG Grafik auf der Seite erfolgt über das <img>-Tag und dem entsprechenden "src" Attribut in HTML. Das Einbinden der exportierten Grafik kann auch in CSS erfolgen. Über CSS kann auch das Stylen der Elemente erfolgen. Das selektieren erfolgt genau wie die Selektierung der HTML-Elemente. Über das DOM haben wir auch Zugriff auf die Elemente der Grafik, dadurch können wir Eventlistener registrieren oder auf sonstige Weise die Elemente manipulieren.


Weiter mit 3D-Grafiken