Generierte Vektorgrafik (canvas-Element)

Das mit HTML5 neu eingeführte canvas-Element ist neben SVG die andere Möglichkeit, um Vektorgrafik in HTML einzubinden. Das canvas-Element ist dabei allerdings nur ein Behälter, eine Aktionsfläche mit definierten Ausmaßen. Was innerhalb davon geschieht, wird durch Scripting, also durch Programmierung erreicht. Bislang gab es jedoch in ECMA/JavaScript keine geeigneten Objekte für Vektorgrafik. Deshalb hat der HTML5-Standard gleich ein solches Objekt mit definiert: den CanvasRenderingContext2D. Das bedeutet aber auch: das canvas-Element ist nicht automatisch ein Container für dieses Objekt, und seine Fähigkeiten sind nicht auf die Möglichkeiten dieses Objekts beschränkt. Das CanvasRenderingContext2D-Objekt ist nur eine zunächst mal mit auf den Weg gegebene Anwendungsmöglichkeit für canvas.

Hinweise zu CanvasRenderingContext2D

Wenn Sie keine Programmierkenntnisse haben, werden Sie möglicherweise nicht alle Inhalte der Beispiele in diesem Abschnitt verstehen. Das ist normal und unvermeidbar. Der Buchabschnitt soll Sie jedoch auch ohne große Programmierkenntnisse dazu befähigen, einfache Vektorgrafiken mit JavaScript und CanvasRenderingContext2D zu erzeugen.

Dabei wird nicht der gesamte Funktionsumfang des CanvasRenderingContext2D-Objekts berücksichtigt. In der HTML-Canvas-Referenz werden alle Eigenschaften und Methoden des CanvasRenderingContext2D-Objekts aufgelistet.

Andere Einführungen und Beispiele im Web:

Canvas mit 2D-Rendering-Context

Sie können einen Canvas-Bereich für eine Vektorgrafik definieren. In einem Script-Bereich stellen Sie dann einen Bezug zu dem canvas-Element her, indem Sie ein CanvasRenderingContext2D-Objekt erzeugen. Wurde das Objekt erfolgreich erzeugt, können Sie Methoden (Funktionen) dieses Objekts aufrufen, um vektorgrafische Inhalte zu erzeugen.

Beispiel

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Information</title> 
</head> 
<body>
<canvas id="info" width="400" height="600">
<img src="info.png" alt="Information">
</canvas>
<script>
var infoPic = document.getElementById('info');
if (infoPic.getContext) {
   infoPic = infoPic.getContext('2d');
   infoPic.fillStyle = "#AAAAAA";
   infoPic.fillRect(0, 0, 140, 360);
   infoPic.fillStyle = "#FF8800";
   infoPic.fillRect(20, 130, 100, 200);
   infoPic.fillStyle = "#880088";
   infoPic.beginPath();
   infoPic.arc(70, 70, 50, 0, 2 * Math.PI, true);
   infoPic.fill();
   infoPic.fillStyle = "#880088";
   infoPic.font = "bold 14px Arial,sans-serif";
   infoPic.fillText  ("NFORMATION", 22, 325);
}
</script>
</body>
</html>

Erläuterung

Das Beispiel erzeugt zum besseren Vergleich die gleiche Grafik wie die Beispiele im Abschnitt SVG-Grafiken (direkt eingebettet). In diesem Fall wird jedoch anstelle von SVG das canvas-Element verwendet. Das canvas-Element wird an der Stelle im HTML-Code notiert, an der die Grafik erscheinen soll.


Gleiche Grafik wie im SVG-Beispiel, hier mit CanvasRenderingContext2D-Objekt

Das Element erhält im einleitenden <canvas>-Tag die Attribute id, width und height. Mit id vergeben Sie einen dokumentweit eindeutigen Namen für das Element. Über diesen Namen können Sie in JavaScript auf das Element zugreifen. Im obigen Beispiel erhält das Element den id-Namen info. Mit dem width-Attribut bestimmen Sie die Anzeigebreite des canvas-Elements in Pixeln, und mit height die Höhe, ebenfalls in Pixel. Die Angaben zu width und height haben ebenso wie bei Pixelgrafikreferenzen die Aufgabe, den Bildschirmaufbau zu optimieren. Wählen Sie die Größen für width und height so, dass der Inhalt der zu generierenden Grafik in den so definierten Ausschnitt passt.

Als Inhalt sollte das canvas-Element alternativen Inhalt erhalten, falls der Browser das canvas-Element nicht kennt oder nicht interpretieren kann (zum Beispiel, weil der Anwender JavaScript deaktiviert hat). Dieser alternative Inhalt sollte wenn möglich einen halbwegs brauchbaren Ersatz bieten. Geeignet ist wie im obigen Beispiel gezeigt eine gewöhnliche Pixelgrafikreferenz, wobei die darin referenzierte Grafik die Vektorgrafik in Form einer Pixelgrafik wiedergibt, oder, falls es sich im Canvas-Bereich um dynamischen Inhalt handelt, einen Screenshot davon.

Das, was im so definierten Canvas-Bereich eigentlich angezeigt werden soll, wird in einem Script-Bereich erzeugt, der sich außerhalb des canvas-Elements befindet, auf das er sich bezieht. Der Script-Bereich wird durch <script>…</script> markiert. Wenn der Inhalt so wie im obigen Beispiel aus JavaScript-Code besteht, der beim Einlesen sofort ausgeführt wird, dann muss der Scriptbereich irgendwo unterhalb und darf keinesfalls vor dem canvas-Element notiert werden, auf das Bezug genommen wird.

Der Inhalt des Scripts gehört nicht zu HTML. Es handelt sich um JavaScript-Code. Im obigen Beispiel sind typische JavaScript-Anweisungen für das CanvasRenderingContext2D-Objekt notiert. Zunächst wird mit der DOM-Methode document.getElementById('info') auf das HTML-Element mit dem id-Namen info zugegriffen — im obigen Beispiel also auf das canvas-Element, das diesen Namen beim id-Attribut erhalten hat. Das Elementobjekt wird in einer Variablen mit Namen infoPic gespeichert. Dadurch ist im weiteren Scriptverlauf der bequeme Zugriff auf das Element über diese Variable möglich.

Mit der Bedingung if (infoPic.getContext) wird überprüft, ob der ausführende Browser in Bezug auf das in infoPic gespeicherte canvas-Elementobjekt das CanvasRenderingContext2D-Objekt kennt. Denn nur dann wird er mit den Anweisungen, welche die Grafik erzeugen, etwas anfangen können. Die entsprechenden Anweisungen sind deshalb in einen Anweisungsblock, markiert durch geschweifte Klammern { und }, eingeschlossen. Die Anweisungen werden nur ausgeführt, wenn die if-Bedingung erfüllt ist.

Weitere Hinweise

Wenn sich Formen auf Grund ihrer Position und Größe überdecken, überdecken später notierte Formen früher notierte. Durch einfaches Umstellen der Reihenfolge können Sie die Überdeckung also beeinflussen.

Mögliche Anweisungen zum Erzeugen von canvas-2D-Vektorgrafiken, ihre Parameter usw. werden weiter unten beschrieben.

Referenzinformationen

HTML5 XHTML5 MSIE FFOX CHROME SAF3.0 OPERA9.0
HTML4.0 XHTML1 MSIE FFOX CHROME SAF OP
HTML3.2 XHTML1 MSIE FFOX CHROME SAF OP

Einfaches Funktions-Set für 2D-Rendering-Context

Beim Generieren einer Grafik im 2D-Rendering-Context kommen immer wieder die gleichen Anweisungsfolgen vor. Es bietet sich daher an, diese Anweisungsfolgen in eine kleine Funktionsbibliothek zu packen und dann beim Generieren der Grafik vorzugsweise diese Funktionen aufzurufen.

Nachfolgend wird eine eine solche Funktionsbibliothek vorgestellt. Sie ist bewusst einfach gehalten und übernimmt nur häufig benötigte Standardaufgaben.

Beispiel

<head>
<!-- andere Angaben im Dokumentkopf -->
<script>
var stroke = false;

function rect(obj, x, y, width, height, rx, ry) {
   obj.beginPath();
   obj.moveTo(x + rx, y);
   obj.lineTo(x + width - rx, y);
   obj.quadraticCurveTo(x + width, y, x + width, y + ry);
   obj.lineTo(x + width, y + height - ry);
   obj.quadraticCurveTo(x + width, y + height, x + width - rx, y + height);
   obj.lineTo(x + rx, y + height);
   obj.quadraticCurveTo(x, y + height, x, y + height - ry);
   obj.lineTo(x, y + ry);
   obj.quadraticCurveTo(x, y, x + rx, y);
   obj.fill();
   if(stroke) obj.stroke();
   obj.closePath();
}

function circle(obj, cx, cy, r) {
   obj.beginPath();
   obj.arc(cx, cy, r, 0, 2 * Math.PI, true);
   obj.fill();
   if(stroke) obj.stroke();
   obj.closePath();
}

function ellipse(obj, x, y, w, h) {
   x = x - w;
   y = y - h;
   w = w * 2;
   h = h * 2;
   var kappa = .5522848;
   ox = (w / 2) * kappa;
   oy = (h / 2) * kappa;
   xe = x + w;
   ye = y + h;
   xm = x + w / 2;
   ym = y + h / 2; 
   obj.beginPath();
   obj.moveTo(x, ym);
   obj.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
   obj.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
   obj.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
   obj.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
   obj.fill();
   if(stroke) obj.stroke();
   obj.closePath();
}

function polygon(obj, points) {
   xy = points.split(" ");
   obj.beginPath();
   if(xy.length > 0) {
      xyn = xy[0].split(",");
      obj.moveTo(xyn[0], xyn[1]);
   }
   for(i = 1; i < xy.length; i++) {
      xyn = xy[i].split(",");
      obj.lineTo(xyn[0], xyn[1]);
   }
   xyn = xy[0].split(",");
   obj.lineTo(xyn[0],xyn[1]);
   obj.fill();
   if(stroke) obj.stroke();
   obj.closePath();
}

function line(obj, x1, y1, x2, y2, sWidth) {
   obj.beginPath();
   obj.moveTo(x1, y1);
   obj.lineTo(x2, y2);
   obj.lineWidth = sWidth;
   obj.stroke();
   obj.closePath();
}

function setFill(obj, col) {
   obj.fillStyle = col;
   obj.strokeStyle = col;
}

function setStroke(obj, col, sWidth) {
   stroke = true;
   obj.strokeStyle = col;
   obj.lineWidth = sWidth;
}

function unset(obj) {
   stroke = false;
   obj.fillStyle = "#000000";
   obj.strokeStyle = "#000000";
   obj.lineWidth = 1;
}

function setLinearFill(obj, col1x, col1y, col2x, col2y, col1, col2) {
   var gradient = obj.createLinearGradient(col1x, col1y, col2x, col2y);
   gradient.addColorStop(0, col1);
   gradient.addColorStop(1, col2); 
   obj.fillStyle = gradient;
}

function setRadialFill(obj, col1x, col1y, col1r, col2x, col2y, col2r, col1, col2) {
   var gradient = obj.createRadialGradient(col1x, col1y, col1r, col2x, col2y, col2r);
   gradient.addColorStop(0, col1);
   gradient.addColorStop(1, col2); 
   obj.fillStyle = gradient;
}

function text(obj, x, y, text, style) {
   if(style) obj.font = style;
   obj.fillText(text, x, y);
}
</script>
</head>

Erläuterung

Die Funktionen werden in einem eigenen Script-Bereich notiert, markiert durch <script>…</script>. Dieser wird in den Dokument-Kopfdaten notiert. Sie haben dabei zwei Möglichkeiten. Die eine ist die oben im Beispiel gezeigte. Dabei notieren die Funktionen innerhalb des Elementinhalts von <script>…</script>. Das ist am performantesten, hat aber den Nachteil, dass Sie den Code in jeder einzelnen Webseite, in der Sie ihn verwenden möchten, notieren müssen. Das ist nicht sehr änderungsfreundlich, wenn Sie beispielsweise die Funktionsbibliothek erweitern möchten. Die andere Möglichkeit besteht darin, den obigen Inhalt des script-Elements in einer eigenen, separaten Datei zu notieren. Diese Datei erhält einen Namen mit der Dateiendung .js, also beispielsweise canvas-2d-functions.js. In HTML notieren Sie dann einfach nur noch: <script src="/canvas-2d-functions.js"></script>. So binden Sie die Datei mit den Funktionen ein.

Das Script besteht aus einer globalen Variablen namens stroke, die aber nur intern von Bedeutung ist, sowie diversen Funktionen. Alle Funktionen erwarten als ersten Parameter (obj) ein gültiges Canvas-Elementobjekt. Wie Sie ein solches Objekt erzeugen, wurde im Beispiel weiter oben gezeigt:

<canvas id="info" width="400" height="600">...</canvas>
<script>
var infoPic = document.getElementById('info');
...
</script>

Dabei ist infoPic ein gültiges Canvas-Elementobjekt.

Nachfolgend werden die Funktionen der kleinen Funktionsbibliothek näher beschrieben.

function rect(obj, x, y, width, height, rx, ry)

Zeichnet ein Rechteck.

  • Parameter obj = Ein canvas-Elementobjekt.
  • Parameter x = Horizontalversatz der linken oberen Ecke des Rechtecks.
  • Parameter y = Vertikalversatz der linken oberen Ecke des Rechtecks.
  • Parameter width = Breite des Rechtecks.
  • Parameter height = Höhe des Rechtecks.
  • Parameter rx = Wenn das Rechteck abgerundete Ecken haben soll: horizontale Abrundung. Wenn keine runden Ecken erwünscht sind, 0 übergeben.
  • Parameter ry = Wenn das Rechteck abgerundete Ecken haben soll: vertikale Abrundung. Wenn keine runden Ecken erwünscht sind, 0 übergeben.

Eigentlich ist es mit der Methode fillRect() ganz einfach, ein Rechteck direkt zu erzeugen. Um jedoch die aus dem <rect>-Element von SVG her bekannte Möglichkeit der runden Ecken nachzubilden, ist etwas mehr Aufwand erforderlich. Das Rechteck wird innerhalb der Funktion rect() Stück für Stück gezeichnet. Das Zeichnen wird durch die Methode beginPath() eingeleitet und durch das Gegenstück closePath() beendet. moveTo() setzt den „Zeichenstift“ auf eine Anfangsposition. Mit lineTo() werden Linien gezeichnet, und mit quadraticCurveTo() einfache Kurven. Durch lineTo() entstehen also die Seiten des Rechtecks, und durch quadraticCurveTo() die runden Ecken, wobei letztere nur optisch sichtbar sind, wenn die Parameter rx bzw. ry größer als 0 sind.

function circle(obj, cx, cy, r)

Zeichnet einen Kreis.

  • Parameter obj = Ein canvas-Elementobjekt.
  • Parameter cx = Horizontalversatz des Kreismittelpunktes.
  • Parameter cy = Vertikalversatz des Kreismittelpunktes.
  • Parameter r = Größe des Radius.

Die Kreisfunktionalität wird intern durch den etwas komplizierten Aufruf der Methode arc() realisiert. Ein Kreis ist dabei nichts anderes als ein 360°-Bogen. Deshalb ist auch die Angabe 2 * Math.PI als Wert eines der Methodenparameters erforderlich. Math ist ein JavaScript-Objekt, und PI die bekannte geometrische Konstante für Kreis- und Bogenberechnung.
Die Funktion circle() ist dem SVG-Element <circle> nachempfunden.

function ellipse(obj, x, y, w, h)

Zeichnet eine Ellipse

  • Parameter obj = Ein canvas-Elementobjekt.
  • Parameter x = Horizontalversatz des Ellipsenmittelpunktes.
  • Parameter y = Vertikalversatz des Ellipsenmittelpunktes.
  • Parameter w = Horizontaler Radius bzw. die halbe Maximalbreite der Ellipse.
  • Parameter h = Vertikaler Radius bzw. die halbe Maximalhöhe der Ellipse.

Das Erzeugen einer Ellipse ist im 2D-Rendering-Context nicht trivial, da die Ellipse einzeln durch vier aneinander gereihte Bezierkurven erzeugt werden muss. Dazu dient die Methode bezierCurveTo(). Damit die Bezierkurven die gewünschte Krümmung erhalten, müssen zuvor geeignete Kurvenkontrollpunkte definiert werden. Dabei kommt auch die geometrische Konstante Kappa zum Einsatz.
Die Funktion ellipse() ist dem SVG-Element <ellipse> nachempfunden.

function polygon(obj, points)

Zeichnet ein Polygon mit einer beliebigen Anzahl von Ecken (auch für Dreiecke geeignet).

  • Parameter obj = Ein canvas-Elementobjekt.
  • Parameter points = Die Eckpunkte des Polygons in Form einer Zeichenkette, die in Anführungszeichen "…" oder '…' eingeschlossen werden muss und folgenden Aufbau hat: Eckpunkte werden durch x,y definiert (ohne Leerzeichen dazwischen) und durch genau ein Leerzeichen voneinander getrennt. Beispiel: "30,40 90,230 60,450". Der Wert vor dem Komma ist jeweils der Horizontalversatz des Eckpunkts, und der Wert hinter dem Komma der Vertikalversatz des Eckpunkts. Das Polygon wird automatisch geschlossen, indem der letzte Eckpunkt mit dem ersten verbunden wird. Mit drei Eckpunkten können Sie ein Dreieck erzeugen.

Die Funktion parst die übergebene Zeichenkette points und zeichnet mit der lineTo()-Methode Linien zwischen den einzelnen Eckpunkten.
Die Funktion polygon() ist dem SVG-Element <polygon> nachempfunden.

function line(obj, x1, y1, x2, y2, sWidth)

Zeichnet eine Linie.

  • Parameter obj = Ein canvas-Elementobjekt.
  • Parameter x1 = Horizontalversatz des einen Eckpunkts der Linie.
  • Parameter y1 = Vertikalversatz des einen Eckpunkts der Linie.
  • Parameter x2 = Horizontalversatz des anderen Eckpunkts der Linie.
  • Parameter y2 = Vertikalversatz des anderen Eckpunkts der Linie.
  • Parameter sWidth = Linienstärke.

Die Funktion line() ist dem SVG-Element <line> nachempfunden und übernimmt das Positionieren und Zeichnen einer Linie. Die Linienstärke muss angegeben werden und bedeutet die Linienstärke in Pixeln. Ohne die Angabe wäre die Linie nicht sichtbar.

function setFill(obj, col)

Setzt die Füllfarbe für nachfolgende Formen. Musss also aufgerufen werden, wenn ein nachfolgender Aufruf etwa von rect(), circle() usw. ein farbiges Objekt erzeugen soll.

  • Parameter obj = Ein canvas-Elementobjekt.
  • Parameter col = Füllfarbe in Form einer Zeichenkette, eingeschlossen in "…" oder '…'. Bei Farbangaben gelten die gleichen Regeln wie für Farbwerte und Farbnamen in CSS. Möglich sind Angaben wie #DD6600, rgb(50,50,200), rgb(100%,80%,10%) oder powderblue.

Die Funktion ruft die Eigenschaften fillStyle und strokeStyle des CanvasRenderingContext2D-Objekts auf.

function setStroke(obj, col, sWidth)

Setzt die Umrissfarbe für nachfolgende Formen. Muss aufgerufen werden, wenn ein nachfolgender Aufruf etwa von rect(), circle() usw. ein Objekt mit sichtbarer/andersfarbiger Umrisslinie erzeugen soll.

  • Parameter obj = Ein canvas-Elementobjekt.
  • Parameter col = Füllfarbe in Form einer Zeichenkette, eingeschlossen in "…" oder '…'. Bei Farbangaben gelten die gleichen Regeln wie für Farbwerte und Farbnamen in CSS.
  • Parameter sWidth = Linienstärke des Umrisses.

function unset(obj)

Löscht gesetzte Füll- und Umrissdefinitionen.

  • Parameter obj = Ein canvas-Elementobjekt.

Diese Funktion ist dazu da, um die Wirkung der Funktionen setFill() und setStroke() wieder aufzuheben. Werden einmal gesetzte Werte für Füllung und/oder Umriss nicht wieder entfernt, gelten sie für alle weiteren erzeugten Formen.

function setLinearFill(obj, col1x, col1y, col2x, col2y, col1, col2)

Definiert einen linearen Farbübergang als Füllung.

  • Parameter obj = Ein canvas-Elementobjekt.
  • Parameter col1x = Horizontalversatz des Startpunkts für Farbe 1.
  • Parameter col1y = Vertikalversatz des Startpunkts für Farbe 1.
  • Parameter col2x = Horizontalversatz des Startpunkts für Farbe 2.
  • Parameter col2y = Vertikalversatz des Startpunkts für Farbe 1.
  • Parameter col1 = Farbe 1 in Form einer Zeichenkette, eingeschlossen in "…" oder '…'. Bei Farbangaben gelten die gleichen Regeln wie für Farbwerte und Farbnamen in CSS.
  • Parameter col2 = Farbe 2 in Form einer Zeichenkette.

Die Eckpunkte für die beiden „Farbstopps“ müssen Sie so wählen, dass diese für eine Form passen, auf die Sie den Farbübergang anwenden möchten. Siehe dazu das Beispiel weiter unten.

Intern ruft die Funktion die Objektmethode createLinearGradient() auf, mit deren Hilfe lineare Farbübergänge im im 2D-Rendering-Context erzeugt werden. Dabei wird ein Unterobjekt erzeugt, das innerhalb der Funktion in der Variablen gradient gespeichert wird. Darauf wiederum lässt sich die Methode addColorStop() anwenden, welche die beiden Farben des Übergangs setzt. Durch Zuweisen des Unterobjekts mit dem Namen gradient an die Objekteigenschaft fillStyle wird der Farbübergang mit dem Objekt verknüpft.

function setRadialFill(obj, col1x, col1y, col1r, col2x, col2y, col2r, col1, col2)

Definiert einen radialen Farbübergang als Füllung.

  • Parameter obj = Ein canvas-Elementobjekt.
  • Parameter col1x = Horizontalversatz des Startpunkts für Farbe 1.
  • Parameter col1y = Vertikalversatz des Startpunkts für Farbe 1.
  • Parameter col1r = Radius (Ausbreitungsweise) für Farbe 1.
  • Parameter col2x = Horizontalversatz des Startpunkts für Farbe 2.
  • Parameter col2y = Vertikalversatz des Startpunkts für Farbe 1.
  • Parameter col2r = Radius (Ausbreitungsweise) für Farbe 2.
  • Parameter col1 = Farbe 1 in Form einer Zeichenkette, eingeschlossen in "…" oder '…'. Bei Farbangaben gelten die gleichen Regeln wie für Farbwerte und Farbnamen in CSS.
  • Parameter col2 = Farbe 2 in Form einer Zeichenkette.

Die interne Vorgehensweise ist dabei analog zu der bei setLinearFill(), mit dem Unterschied, dass zusätzlich die Parameter col1r und col2r übergeben werden. Diese legen den Ausbreitungsradius der jeweiligen Farbe fest. Intern ruft die Funktion anstelle von createLinearGradient() die entsprechende Methode createRadialGradient() auf. Diese setzt den radialen Farbverlauf.

function text(obj, x, y, text, style)

Fügt einen formatierten Text ein.

  • Parameter obj = Ein canvas-Elementobjekt.
  • Parameter x = Horizontalversatz der Textanfangsposition.
  • Parameter y = Vertikalversatz der Textanfangsposition. Orientiert sich an der Basislinie der Schrift.
  • Parameter text = Der auszugebende Text.
  • Parameter style = Zeichenkette, markiert durch "…" oder '…', mit folgenden Angaben: Schriftgewicht (bold für Fettschrift oder normal für Normalschrift), Schriftgröße (z.B. 18px) und Schriftart (z.B. Arial,sans-serif). Die einzelnen Angaben werden durch Leerzeichen getrennt.

Die Schriftfarbe kann durch vorherigen Aufruf der Funktion setStroke() bestimmt werden.

Anwendung des Funktions-Sets

Nachfolgend werden zum besseren Vergleich die gleichen Beispiele entwickelt wie im Buchabschnitt über SVG-Grafiken (direkt eingebettet).

Formen zeichnen

Dieses Beispiel zeichnet mit Hilfe der obigen Funktionsbibliothek ein Rechteck, einen Kreis, eine Ellipse, ein Polygon und zwei Linien.

<!doctype html>
<head>
<!-- andere Angaben im Dokumentkopf -->
<script>
   <!-- Code der Funktionsbibliothek -->
</script>
</head> 
<body>
   <!-- andere Inhalte im Dokumentkörper -->
   <canvas id="formen" width="260" height="600"></canvas>
   <script>
      var formobj = document.getElementById('formen').getContext('2d');
      rect(formobj, 40, 20, 200, 40, 5, 5);
      circle(formobj, 140, 140, 60);
      ellipse(formobj, 140, 240, 60, 20);
      polygon(formobj, "40,280 240,280 140,360");
      line(formobj, 20, 20, 20, 380, 3);
      line(formobj, 10, 370, 240, 370, 3);
   </script>
   <!-- andere Inhalte im Dokumentkörper -->
</body>
</html>

Gleiche Grafik wie im SVG-Beispiel für Formen, hier mit CanvasRenderingContext2D-Objekt

Das Beispiel demonstriert noch einmal den grundsätzlichen Aufbau. Im Dokumentkopf wird in einem script-Bereich die Funktionsbibliothek eingebunden. Im Dokumentkörper wird an gewünschter Stelle ein canvas-Element notiert, das neben Angaben zu Breite und Höhe einen id-Namen erhält. In einem weiteren script-Bereich wird zunächst eine Variable definiert, die im Beispiel formobj genannt wird. Durch ihre Wertzuweisung wird sie zu einer Objektvariablen, die den Funktionen der Funktionsbibliothek als jeweils erster Parameter übergeben werden kann. Die Wertzuweisung besteht aus einem direkten DOM-Zugriff auf das canvas-Element (document.getElementById('formen')). Dabei ist formen der id-Name des canvas-Elements. Angehängt wird ein Aufruf der Methode getContext('2d'), die den Bezug zum CanvasRenderingContext2D herstellt.

Umrisse und Füllungen

Dieses Beispiele versieht einzelne Formen zusätzlich mit Füllfarben und andersfarbigen Umrisslinien in frei definierbarer Linienstärke.

<!doctype html>
<head>
<!-- andere Angaben im Dokumentkopf -->
<script>
   <!-- Code der Funktionsbibliothek -->
</script>
</head> 
<body>
   <!-- andere Inhalte im Dokumentkörper -->
   <canvas id="farbige_formen" width="260" height="600"></canvas>
   <script>
      var farbformobj = document.getElementById('farbige_formen').getContext('2d');
      setFill(farbformobj, "#DD6600");
      rect(farbformobj, 40, 20, 200, 40, 5, 5);
      setFill(farbformobj, "rgb(100%,80%,10%)");
      setStroke(farbformobj, "rgb(50,50,200)", 6);
      circle(farbformobj, 140, 140, 60);
      unset(farbformobj);
      setFill(farbformobj, "powderblue");
      polygon(farbformobj, "40,220 240,220 140,360");
   </script>
   <!-- andere Inhalte im Dokumentkörper -->
</body>
</html>

Gleiche Grafik wie im SVG-Beispiel für Füllungen und Umrisse, hier mit CanvasRenderingContext2D-Objekt

In diesem Beispiel geschieht im Wesentlichen das Gleiche wie im Beispiel zuvor. Zwischen den Funktionsaufrufen für Formen wie Rechteck, Kreis oder Polygon sind jedoch Aufrufe der Funktionsbibliotheksaufrufe setFill(), setStroke() und unset() notiert. Dadurch werden die Farben und Umrisse für jeweils nachfolgende Formen gesteuert.

Farbverläufe

In diesem Beispiel werden Formen nicht mit einfachen Farben gefüllt, sondern mit linearen oder radialen Farbverläufen.

<!doctype html>
<head>
<!-- andere Angaben im Dokumentkopf -->
<script>
   <!-- Code der Funktionsbibliothek -->
</script>
</head> 
<body>
   <!-- andere Inhalte im Dokumentkörper -->
   <canvas id="farbverlauf_formen" width="280" height="600"></canvas>
   <script>
      var fvobj = document.getElementById('farbverlauf_formen').getContext('2d');
      setLinearFill(fvobj, 20, 20, 250, 0, "gray", "white");
      rect(fvobj, 20, 20, 250, 100, 0, 0);
      unset(fvobj);
      setLinearFill(fvobj, 20, 140, 20, 240, "gray", "white");
      rect(fvobj, 20, 140, 250, 100, 0, 0);
      unset(fvobj);
      setLinearFill(fvobj, 20, 200, 250, 300, "gray", "white");
      rect(fvobj, 20, 260, 250, 100, 0, 0);
      unset(fvobj);
      setRadialFill(fvobj, 140, 480, 20, 140, 480, 100, "white", "gray");
      circle(fvobj, 140, 480, 100);
   </script>
   <!-- andere Inhalte im Dokumentkörper -->
</body>
</html>

Gleiche Grafik wie im SVG-Beispiel für Farbverläufe, hier mit CanvasRenderingContext2D-Objekt

Durch Aufrufe der Funktionen setLinearFill() und setRadialFill() aus der Funktionsbibliothek werden Farbverläufe für jeweils nachfolgend notierte Formen definiert.

Text hinzufügen

<!doctype html>
<head>
<!-- andere Angaben im Dokumentkopf -->
<script>
   <!-- Code der Funktionsbibliothek -->
</script>
</head> 
<body>
   <!-- andere Inhalte im Dokumentkörper -->
   <canvas id="text" width="580" height="820"></canvas>
   <script>
      var textobj = document.getElementById('text').getContext('2d');
      setFill(textobj, "#880088");
      text(textobj, 10, 30, "Der Hase im Pfeffer", "normal 28px Arial");
      setFill(textobj, "rgb(0,176,0)");
      text(textobj, 20, 70, "Des Pudels Kern", "bold 36px Trebuchet MS,serif");
      setFill(textobj, "red");
      textobj.rotate(90 * (Math.PI / 180));
      text(textobj, 3, -310, "Tiere", "bold 28px Arial");
      textobj.rotate(180 * (Math.PI / 180));
      text(textobj, -70, 350, "Wahrheit", "bold 14px Arial");
   </script>
   <!-- andere Inhalte im Dokumentkörper -->
</body>
</html>

Gleiche Grafik wie im SVG-Beispiel für Text, hier mit CanvasRenderingContext2D-Objekt

Die Funktion text() zeichnet den eigentlichen Text. Die Textfarbe wird zuvor jeweils durch Aufruf von setFill() gesetzt. Neu ist in diesem Beispiel die Anwendung der rotate()-Methode des CanvasRenderingContext2D-Objekts. Diese Methode erwartet als Parameter eine Winkelangabe. Übergeben Sie den Ausdruck n * (Math.PI / 180), wobei n der gewünschte Neigungswinkel ist. Im Beispiel wird das Objekt vor dem Ausgeben des Worts Tiere um 90 Grad geneigt, und vor der Ausgabe des Worts Wahrheit um weitere 180 Grad.

Eingebettete Pixelgrafik und transparenter Text

Die vektorgrafischen Bestandteile einer Canvas-Grafik können auch um eingebettete Pixelgrafiken erweitert werden. Durch Kombination etwa mit Transparenzeffekten lassen sich dabei interessante Effekte erzielen.

<!doctype html>
<head>
<!-- andere Angaben im Dokumentkopf -->
<script>
   <!-- Code der Funktionsbibliothek -->
</script>
</head> 
<body>
   <!-- andere Inhalte im Dokumentkörper -->
   <canvas id="bild" width="700" height="600"></canvas>
   <script>
      var bildobj = document.getElementById('bild').getContext('2d');
      var img = new Image();
      img.src = "madrid.jpg";
      img.onload = function() {
      bildobj.drawImage(img, 50, 50);
      setFill(bildobj, "#555555");
      bildobj.globalAlpha = 0.5;
      text(bildobj, 0, 150, "MADRID", "bold 160px Impact");
      bildobj.globalAlpha = 0.8;
      setLinearFill(bildobj, 460, 180, 700, 240, "white", "black");
      text(bildobj, 400, 180, "ESPAGNA", "bold 80px Impact");
      }
   </script>
   <!-- andere Inhalte im Dokumentkörper -->
</body>
</html>

Foto mit transparenten Schriftzügen

In JavaScript besteht die Möglichkeit, Objekte für Grafiken zu erzeugen. Im Beispiel wird mit var img = new Image(); ein neues Grafikobjekt erzeugt. Mit img.src = "madrid.jpg"; wird diesem Objekt eine Grafikdatei zugewiesen.

Das Einbinden einer solchen Grafik in die Canvas-Grafik ist allerdings etwas komplizierter, da die Grafikdatei erst einmal geladen werden muss. Deshalb wird der gesamte nachfolgende Code abhängig gemacht von img.onload, was so viel bedeutet wie „wenn die Grafik geladen ist“. Bei Eintreten dieses Ereignisses wird eine anonyme (nicht benannte) Funktion function() ausgeführt.

Innerhalb der Funktion wird die CanvasRenderingContext2D-Objektmethode drawImage() ausgeführt, die das zuvor erzeugte JavaScript-Grafikobjekt an der xy-Position 50,50 des Canvas-Bereichs platziert. Dort beginnt also die linke obere Ecke der Pixelgrafik.

Die Schriftzüge, die das Foto überdecken, werden mit den entsprechenden Funktionen aus der Funktionsbibliothek erzeugt. Neu ist in diesem Beispiel die Anwendung der Objekteigenschaft globalAlpha. Damit lässt sich der Transparenzfaktor für nachfolgende Formen einstellen. Erlaubt sind Werte zwischen 0 (vollständig transparent) und 1 (überhaupt nicht transparent). Ein Wert wie 0.5 (bitte immer den Punkt als Fließkommazeichen verwenden!) bewirkt also eine 50%ige Transparenz.

Der Verlaufseffekt beim Schriftzug ESPAGNA wird durch Anwenden der Funktion setLinearFill() vor Aufruf der Funktion text() erreicht. Farbügergänge lassen sich nämlich auch auf Texte anwenden.

 


Korrekturen, Hinweise und Ergänzungen
Bitte scheut euch nicht und meldet, was auf dieser Seite sachlich falsch oder irreführend ist, was ergänzt werden sollte, was fehlt usw. Dazu bitte oben aus dem Menü Seite den Eintrag Diskutieren wählen. Es ist keine Anmeldung erforderlich, um Anmerkungen zu posten. Unpassende Postings, Spam usw. werden allerdings kommentarlos entfernt.

Sofern nicht anders angegeben, steht der Inhalt dieser Seite unter Lizenz Creative Commons Attribution-ShareAlike 3.0 License