Homepage-Webhilfe Event-Banner

Canvas

Bei einem Canvas (engl. für Leinwand) handelt es sich um ein HTML-Element, mit welchem wir eine Zeichenfläche (also sozusagen eine Leinwand) definieren können. Die Zeichenfläche wird dabei in HTML über das canvas-Element angelegt. Der Zeichenvorgang erfolgt dann mittels JavaScript.

Das canvas-Element ist zweiteilig, wovon zwischen den Tags ein Text angegeben werden kann, welcher angezeigt werden soll, wenn das Element nicht unterstützt wird. Die Größe der Zeichenfläche wird in Pixel durch die Attribute width und height (Angabe ohne px-Suffix) angegeben. Beide Attribute sollten dabei für ein korrektes Verhalten angegeben werden. Um das canvas-Element anzusprechen, können wir diesem z. B. eine ID geben (siehe Beispiel).

<canvas id="zeichnung" width="400" height="200"></canvas>

Um in JavaScript nun auf die Zeichenfläche zuzugreifen, müssen wir das Node-Objekt des Elements laden (im Beispiel mittels getElementById()) und die Funktion getContext() mit der Zeichenkette "2d" als Parameter aufrufen.

var ctx = document.getElementById("zeichnung").getContext("2d");

Übrigens: Der oft verwendete Variablenname ctx, im Bezug auf Zeichenflächen, stellt die Abkürzung für context dar.

Bevor wir im nächsten Schritt damit beginnen, unsere ersten Rechtecke zu zeichnen, wollen wir zuerst noch ein paar Eigenschaften vorstellen. Der Eigenschaft strokeStyle kann ein Farbwert zugewiesen werden und stellt somit die Linienfarbe dar. Als Angabe sind, so wie in CSS auch, Farbnamen, RGB-Werte, RGBA-Werte, Hex-Werte, HSL-Werte und HSLA-Werte möglich. Die Eigenschaft fillStyle legt die Farbe zum Ausfüllen (Füllfarbe) fest. Beide Eigenschaften können während des kompletten Zeichenvorgangs mehrmals geändert werden, sodass z. B. die eine Linie rot gefärbt wird und die andere blau. Mit Hilfe der Eigenschaft lineWidth lässt sich die Breite der Linie (Strichstärke) ändern. Die Angabe erfolgt als Pixel-Wert (ohne Einheit), wovon 1 die Standardeinstellung ist. Natürlich gibt es noch viele weitere Eigenschaften, diese sind für den Anfang jedoch nicht relevant und werden nur selten benutzt.


Um Rechtecke ohne Pfade zu zeichnen (dazu im nächsten Schritt mehr), gibt es die Funktionen strokeRect() und fillRect(). Die Funktion strokeRect() erzeugt ein Rechteck ohne „Füllung“ ggf. jedoch mit einem Rahmen (je nach Einstellung von strokeStyle und lineWidth). Die Funktion fillRect() hingegen erzeugt ein ausgefülltes Rechteck (jedoch ohne Rahmen). Zur Einstellung der Farbe dient, wie oben bereits beschrieben, die Eigenschaft fillStyle. Beiden Funktionen werden 4 Parameter übergeben, wovon der erste die X-Position und der zweite Y-Position festlegen. Beide Positionen beziehen sich dabei auf die Ecke oben links. Der dritte und vierte Parameter legt die Breite und Höhe fest. Auch hier werden alle Parameterwerte in Pixel als Zahl angegeben.

var ctx = document.getElementById("zeichnung").getContext("2d");

ctx.strokeStyle = "red";
ctx.strokeRect(50, 50, 50, 50);
ctx.strokeStyle = "lime";
ctx.lineWidth = 10;
ctx.strokeRect(200, 10, 60, 80);
ctx.fillStyle = "blue";
ctx.fillRect(150, 110, 200, 80);
Vorschau

Wichtig: Das canvas-Element kann als eine Art Koordinatensystem angesehen werden. Der Nullpunkt (X=0 und Y=0) befindet sich hier jedoch in der Ecke oben links. Haben wir z. B. eine Zeichenfläche mit der Größe von 300x200px, so hat die Ecke unten rechts die Position X=300 und Y=200.


Um Linien oder andere Formen zu zeichnen, gibt es einige weitere Funktionen. Hier spricht man nun zumeist von Pfaden. Ein Pfad (engl. path) kann dabei aus ein oder mehreren Linien (diese können gerade oder gekrümmt sein) bestehen. Um das Zeichnen eines Pfades zu beginnen, müssen wir zuerst die Funktion beginPath() aufrufen. Am Ende der Pfad-Zeichnung rufen wir die Funktion fill() oder stroke() auf. fill() füllt dabei den „gewählten“ Bereich mit der Füllfarbe aus, stroke() hingegen zeichnet lediglich die Kontur.

Zum Zeichnen von Linien gibt es die Funktionen moveTo() und lineTo(). Beiden Funktionen werden als erster Parameter die X-Position und als zweiter Parameter die Y-Position übergeben. Die Funktion moveTo() positioniert lediglich den „Cursor“, wohingegen die Funktion lineTo() eine Linie von der letzten Position bis zur angegebenen Position zeichnet. Eine nützliche Funktion ist closePath(). Mit dieser ist es möglich, wieder an den Ausgangspunkt des Pfades zu springen, um somit eine Form zu schließen.

Die Funktion arc() erlaubt es, einen Kreis bzw. eine Ellipse oder einen Kreisteil bzw. Ellipsenteil zu zeichnen. Der erste Parameter stellt die X-Position des Kreismittelpunkts dar, der zweite Parameter stellt die Y-Position des Kreismittelpunkts dar und der dritte Parameter gibt den Kreisradius an. Des Weiteren benötigen wir noch zwei Parameter, welche die Winkelpositionen angeben. Die Angabe der Winkelpositionen erfolgt mittels der Konstante PI, welche im Math-Objekt hinterlegt ist. So entspricht z. B. 0.5 * Math.PI dem Winkel 90° und 2 * Math.PI 360°. Der vierte Funktionsparameter gibt den Startwinkel an, dabei entspricht 0 der 3-Uhr-Position der Ellipse. Der fünfte Parameter gibt den Endwinkel an.

Mit Hilfe der Funktion arcTo() ist es möglich, eine Kurve bzw. einen Bogen (engl. arc) zu zeichnen. Die Zeichnung erfolgt zwischen zwei Kontrollpunkten, welche als Funktionsparameter (Reihenfolge: x1, y1, x2, y2) übergeben werden müssen. Der fünfte Parameter gibt den Radius des Bogens an. Hier lohnt es sich, mit den Funktionsparametern etwas zu experimentieren, bis man die Funktionsweise der Funktion besser verstanden hat.

Um ein Rechteck mittels Pfade zu zeichnen (z. B. um Transformationen darauf anzuwenden), gibt es die Funktion rect(). Die Funktion rect() hat die gleichen Parameter wie strokeRect() und fillRect().

var ctx = document.getElementById("zeichnung").getContext("2d");

// Zick-Zack-Linien zeichnen
ctx.fillStyle = "red";
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(50, 200);
ctx.lineTo(100, 0);
ctx.lineTo(150, 200);
ctx.lineTo(200, 0);
ctx.lineTo(250, 200);
ctx.lineTo(300, 0);
ctx.lineTo(350, 200);
ctx.lineTo(400, 0);
ctx.fill();

// Dreieck unten mitte
ctx.strokeStyle = "blue";
ctx.beginPath();
ctx.moveTo(175, 200);
ctx.lineTo(200, 100);
ctx.lineTo(225, 200);
ctx.closePath();            // entspricht => ctx.lineTo(175, 200);
ctx.stroke();

// Ellipse unten links
ctx.fillStyle = "lime";
ctx.beginPath();
ctx.arc(100, 150, 25, 0.6 * Math.PI, 1.8 * Math.PI);
ctx.fill();

// kurvige Linie unten rechts
ctx.strokeStyle = "lime";
ctx.beginPath();
ctx.moveTo(280, 200);
ctx.lineTo(290, 150);
ctx.arcTo(300, 130, 310, 150, 10);
ctx.lineTo(320, 200);
ctx.stroke();

// Rechteck oben mitte
ctx.fillStyle = "yellow";
ctx.beginPath();
ctx.rect(150, 25, 100, 50);
ctx.fill();
Vorschau

Zum Zeichnen eines Texts gibt es die Funktion strokeText() und fillText(). Als Parameter wird der Text sowie die X- und Y-Position übergeben. Zum Einstellen der Schriftart, Schriftgröße etc. können wir die Eigenschaft font nutzen. Dabei muss eine Zeichenkette gesetzt werden, welche mehrere Einstellungen umfassen kann. Hier muss vor allem auf die Reihenfolge geachtet werden: font-style, font-variant, font-weight, font-size und font-family. Die Eigenschafts-Namen und Werte sind dabei von CSS abzuleiten.

var ctx = document.getElementById("zeichnung").getContext("2d");

ctx.fillStyle = "red";
ctx.font = "30px Times New Roman";
ctx.fillText("Herzlich Willkommen auf", 20, 75);

ctx.strokeStyle = "blue";
ctx.font = "bold 35px Arial";
ctx.strokeText("Homepage-Webhilfe", 40, 150);
Vorschau

Mit Hilfe der Funktion drawImage() ist es möglich, ein Bild innerhalb des canvas-Elements zu zeichnen. Das Bild selbst muss dabei bereits auf der Seite verwendet werden (mittels img-Element). Wollen wir das Bild ausschließlich im canvas-Element anzeigen, muss das Bild zwar ebenfalls mittels des img-Elements eingebunden werden, jedoch können wir das Bild selbst mit der CSS-Eigenschaft display und dem Wert none (siehe Beispiel) ausblenden. Zusätzlich zu dem Bild (Angabe als Node-Objekt) muss der Funktion noch die X- und Y-Position übergeben werden. Bei Bedarf kann noch zusätzlich die Breite und Höhe angegeben werden.

<img src="/Bilder/Logo/Logo.jpg" alt="Logo" id="logo" style="display: none;" />
<canvas id="zeichnung" width="400" height="200"></canvas>
window.onload = function ()
{
	var ctx = document.getElementById("zeichnung").getContext("2d");
	ctx.drawImage(document.getElementById("logo"), 100, 0, 200, 200);
};
Vorschau

Wichtig: In dem obigen Beispiel ist es nochmals besonders wichtig, dass die Canvas-Funktion drawImage() erst aufgerufen wird, wenn die Seite (und somit auch das Bild) vollständig geladen ist.


Transformationen erlauben es, zu zeichnende Bestandteile, wie z. B. Rechtecke, Linien, Kreise, Texte oder Bilder, zu rotieren, verschieben, skalieren und neigen. Dafür stehen uns die Funktionen rotate(), translate(), scale(), transform() und setTransform() zur Verfügung, welche wir Ihnen gleich noch genauer erklären werden.

Davor wollen wir uns jedoch mit der Funktionsweise aller Transformationsfunktionen sowie den Funktionen save() und resotre() beschäftigen: Alle ausgeführten Transformationen werden gespeichert (und dies nicht nur für den aktuellen Pfad). Dies hat zur Folge, dass wenn wir z. B. zwei Rechtecke zeichnen und beide mittels der rotate()-Funktion und einer Angabe von 1° rotieren, dass das erste Rechteck wie gewollt um 1° rotiert wird, das zweite jedoch schon um 2°. Dies kann u. U. gewünscht sein oder eben auch nicht. Um diesem Szenario entgegenzuwirken, gibt es die Funktionen save() und restore(). Beim Aufruf der Funktion save() werden Transformations-Einstellungen sowie viele andere Parameter (u. a. strokeStyle, fillStyle, lineWidth und font) gespeichert. Um diese Einstellungen wieder zurückzuholen, gibt es die Funktion restore(). Innerhalb eines Zeichenvorgangs kann natürlich mehrmals die Funktion save() und restore() aufgerufen werden. save() baut dabei einen Einstellungsstapel von unten nach oben auf, welcher von restore() von oben nach unten wieder abgebaut wird. Für alle Transformationsfunktionen gilt zusätzlich noch, dass die Transformationen nur für Bestandteile gelten, welche nach dem Aufruf der Transformationsfunktion gezeichnet wurden.

Die Funktion rotate() kann zum Rotieren verwendet werden. Der Funktion muss dabei ein Wert in der Einheit Radiant übergeben werden. Um Grad in Radiant umzuwandeln, gilt die Formel grad * (Math.PI / 180). Die Rotation selbst erfolgt immer vom Nullpunkt der Zeichenfläche aus.

Die Funktion translate() verschiebt den Nullpunkt der Zeichenfläche, wovon zu beachten ist, dass Überstände nicht gezeichnet werden. Als Parameter werden der translate()-Funktion die neue X- und Y-Position übergeben.

Mit Hilfe der Funktion scale() lässt sich eine Zeichnung skalieren. Hierfür werden der Funktion zwei Parameter übergeben, welche den Skalierungsfaktor (z. B. 1 = 100%, 1.5 = 150%) für die X- und Y-Achse festlegen. Bei Verwendung der scale()-Funktion wird neben der Größe (Breite und Höhe) auch die Positionsangabe (X- und Y-Position) skaliert, wovon sich ein Teil des Ergebnisses ähnlich wie eine Verschiebung auswirkt.

Im folgenden Beispiel wird bewusst die Transformation innerhalb der Schleife nicht zurückgesetzt. Das Beispiel zeigt ein blaues Rechteck, welches immer mehr im Uhrzeigersinn rotiert wird, ein rotes Rechteck, welches immer weiter verschoben wird, und ein grünes Rechteck, welches immer größer wird (und somit auch immer weiter verschoben wird).

var ctx = document.getElementById("zeichnung").getContext("2d");

ctx.save();

ctx.fillStyle = "blue";
for (var i = 0; i < 30; i++)
{
	ctx.beginPath();
	ctx.rotate(1 * (Math.PI / 180));
	ctx.rect(100, 50, 100, 50);
	ctx.fill();
}

ctx.restore();
ctx.save();

ctx.fillStyle = "red";
for (var i = 0; i < 30; i++)
{
	ctx.beginPath();
	ctx.translate(1, 1);
	ctx.rect(225, 25, 100, 50);
	ctx.fill();
}

ctx.restore();
ctx.save();

ctx.fillStyle = "lime";
for (var i = 0; i < 5; i++)
{
	ctx.beginPath();
	ctx.scale(1.1, 1.1);
	ctx.rect(195, 95, 25, 25);
	ctx.fill();
}
Vorschau

Neben den zwei bisher vorgestellten Funktionen zur Transformation gibt es noch die Funktionen transform() und setTransform(). Beiden Funktionen werden 6 Parameter übergeben, mit welchen eine Skalierung, Neigung und Verschiebung angegeben werden kann. Dabei muss vor allem auf die Reihenfolge geachtet werden: horizontale Skalierung, horizontale Neigung, vertikale Neigung, vertikale Skalierung, horizontale Verschiebung und vertikale Verschiebung. transform() verhält sich wie die bereits vorgestellten Transformationsfunktionen, d. h. die Transformationseinstellungen werden „gespeichert“ und summieren sich u. U. bei mehrmaligem aufrufen. setTransform() hingegen setzt zuerst die Transformationseinstellungen zurück und führt dann die Transformation aus. Im Beispiel ist dieser Unterschied klar zu erkennen.

var ctx = document.getElementById("zeichnung").getContext("2d");

ctx.save();

ctx.fillStyle = "blue";

for (var i = 0; i < 15; i++)
{
	ctx.beginPath();
	ctx.transform(1, 0, 0, 1, i, i);
	ctx.rect(25, 25, 50, 50);
	ctx.fill();
}

for (var i = 0; i < 15; i++)
{
	ctx.beginPath();
	ctx.setTransform(1, 0, 0, 1, i, i);
	ctx.rect(150, 25, 50, 50);
	ctx.fill();
}

ctx.restore();

ctx.fillStyle = "red";

for (var i = 0; i < 15; i++)
{
	ctx.beginPath();
	ctx.transform(1, 0, (i / 100), 1, 0, 0);
	ctx.rect(250, 25, 50, 50);
	ctx.fill();
}

for (var i = 0; i < 15; i++)
{
	ctx.beginPath();
	ctx.setTransform(1, 0, (i / 100), 1, 0, 0);
	ctx.rect(250, 125, 50, 50);
	ctx.fill();
}
Vorschau
Um unsere Webseite für Sie optimal zu gestalten und fortlaufend verbessern zu können, verwenden wir Cookies. Durch die weitere Nutzung der Webseite stimmen Sie der Verwendung von Cookies zu. Weitere Informationen OK