JavaScript/Canvas/Formen und Pfade
Die Zeichenfläche des canvas ist ein kartesisches Koordinatensystem mit dem Ursprung (0 | 0) in der linken, oberen Ecke. Sie können nun unter Verwendung dieser Koordinaten Rechtecke und komplexere Formen mithilfe von Pfaden zeichnen.
Inhaltsverzeichnis
Rechtecke
Anders als SVG kennt canvas nur das Rechteck als Grundform. Zum Zeichnen von Rechtecken stellt Canvas drei Funktionen zur Verfügung:
-
fillRect(x, y, width, height)
zeichnet ein ausgefülltes Rechteck ohne Rahmen an die angegebene Position mit den angegebenen Maßen. Als Füllung wird die infillStyle
hinterlegte Information verwendet. -
strokeRect(x, y, width, height)
zeichnet ein unausgefülltes Rechteck mit Rahmen. Als Rahmenfüllung wird die instrokeStyle
hinterlegte Information verwendet -
clearRect(x, y, width, height)
setzt einen Ausschnitt der Canvas auf seine Ursprungsfarbe zurück (entweder weiß oder die im entsprechenden style-Bereich festgelegte Hintergrundfarbe).
function zeichne()
{
var element = document.getElementById('canvas');
if(element.getContext)
{
var context = element.getContext('2d');
var grad = context.createLinearGradient(0, 0, 0, 30);
grad.addColorStop(0, "white");
grad.addColorStop(1, "#888888");
context.fillStyle=grad;
context.fillRect(0, 0, 150, 30);
}
}
In diesem Beispiel wird nach dem Ermitteln des 2D-Context mithilfe der Funktion context.createLinearGradient(0, 0, 0, 30)
ein Farbverlauf erzeugt, dessen gedachte Linie senkrecht von oben nach unten verläuft. Diesem Farbverlauf werden danach zwei ColorStops verpasst: der erste befindet sich im Punkt (0 | 0) und legt dort die Farbe Weiß fest, der zwei liegt im Punkt (0 | 30) und definiert dort einen grauen Farbton. Danach wird der so erzeugte Gradient auf die Canvas angewendet, indem er der Membervariable fillStyle
zugewiesen wird. Es entsteht ein Rechteck, welches ähnlich wie ein Button gestaltet ist.
Path
Neben Rechtecken ermöglicht es Canvas, mithilfe von Paths beliebige Polygone und Kurven darzustellen. Ein Path (engl. für Pfad) umfasst dabei beliebig viele Punkte sowie Informationen darüber, wie diese mit ihren jeweiligen Nachbarpunkten verbunden sind.
Hierzu stehen folgende Memberfunktionen zur Verfügung:
beginPath
-
beginPath()
: Löscht alle bisher im Path-Objekt gespeicherten Punkte (dies hat keinen Einfluss auf die Zeichenoberfläche der Canvas), sodass ein neuer Path gezeichnet werden kann.
moveTo
-
moveTo(x, y)
: Setzt den Referenzpunkt, auf den sich Funktionen wielineTo
beziehen, an die Position (x | y), ohne dabei eine Linie zu zeichnen.
beginPath()
aufgerufen wurde, muss vor dem Ausführen einer Path-Funktion (außer rect
) der erste Referenzpunkt mithilfe von moveTo
gesetzt werden, da andernfalls die auf beginPath
folgende Path-Funktion nicht ausgeführt wird.lineTo
-
lineTo(x, y)
: Zeichnet eine Linie vom aktuellen Referenzpunkt zur Position (x | y) und ersetzt danach den Referenzpunkt durch diese Position. -
rect(x, y, width, height)
: Zeichnet ein Rechteck mit der angegebenen Position und Größe. Der Referenzpunkt wird danach auf die Koordinate (x | y) gesetzt.
arc
-
arc(x, y, r, w1, w2, dir)
: Zeichnet von einem Kreis mit dem Mittelpunkt M(x | y) und Radiusr
den Teil des Umfangs, der im Uhrzeigesinn (bzw. im Gegenuhrzeigesinn, soferndir
true ist) zwischen den Winkelnw1
undw2
liegt. Berücksichtigen Sie dabei, dass die Winkel in der Einheit rad interpretiert werden (ihre Angabe erfolgt jedoch als Float-Werte, nicht als CSS-String). Weiterhin müssen Sie beachten, dass zusätzlich noch eine Linie vom bisherigen Referenzpunkt zum Beginn des Kreisbogens (der zuw1
gehörende Punkt) gezogen und danach der Referenzpunkt an die zuw2
gehörende Position gesetzt wird.
arcTo
Die Funktion arcTo(x1, y1, x2, y2, r)
nimmt einen Kreis mit dem Radius r
an, auf dessen Umfang die Punkte P1(x1 | y1) und P2(x2 | y2) liegen. Weiterhin muss sowohl die Gerade, die durch den Referenzpunkt und P1 geht, als auch die Gerade durch die Punkte P1 und P2 Tangente (in den Punkten P1 bzw. P2) an den gesuchten Kreis sein. Von dem Kreis, der diese Bedingungen erfüllt, wird nun derjenige Teil des Umfangs gezeichnet, der im Uhrzeigesinn zwischen den Punkten P1 und P2 liegt. Außerdem wird wie bei arc
eine Linie vom Referenzpunkt zu P1 gezeichnet und P2 zum neuen Referenzpunkt erklärt.
quadraticCurveTo
-
quadraticCurveTo(x1, y1, x2, y2)
: Zeichnet eine quadratische Bézier-Kurve, deren drei Kontrollpunkte der Referenzpunkt, P1(x1 | y1) und P2(x2 | y2) sind . Der Referenzpunkt wird danach durch P2 ersetzt.
bezierCurveTo
-
bezierCurveTo(x1, y1, x2, y2, x3, y3)
: Zeichnet eine kubische Bézierkurve, deren vier Kontrollpunkte der Referenzpunkt, P1(x1 | y1), P2(x2 | y2) und P3(x3 | y3) sind. Der Referenzpunkt wird danach durch P3 ersetzt.
closePath
-
closePath()
: Verbindet den letzten und ersten Punkt des Paths mit einer Linie, letzterer wird danach zum Referenzpunkt.
Gestaltung
stroke
-
stroke()
: Zeichnet den unausgefüllten Path in das Canvas-Element. Als Rahmenfüllung wird die instrokeStyle
hinterlegte Information verwendet.
fill
-
fill()
: Zeichnet den ausgefüllten Path ohne Rahmen. Ist der Path nicht geschlossen, so begrenzt diejenige Gerade die Fläche, die durch Aufrufen der FunktionclosePath()
entstünde (tatsächlich wird diese Funktion allerdings nicht aufgerufen). Als Füllfarbe wird die infillStyle
hinterlegte Information verwendet.
stroke
und fill
) von Zeichnen gesprochen wurde, so ist als Zeichenoberfläche stets das Path-Objekt, nicht das Canvas-Element gemeint. Dies bedeutet, dass lediglich beim Aufrufen von stroke
und fill
das Path-Objekt tatsächlich auf das Canvas-Element gezeichnet wird.weitere Funktionen
Weiterhin existieren noch einige Funktionen, die Paths zum Prüfen und Begrenzen einsetzen:
save
-
save()
: Legt ein komplettes Abbild des aktuellen Context-Objekts inklusive Membervariablen und Path an, sodass das Context-Objekt zu einem späteren Zeitpunkt wieder auf den gespeicherten Zustand zurückgesetzt werden kann.
restore
-
restore()
: Stellt den letzten mithilfe der Funktionsave
gespeicherten Zustand des Context-Objekts wieder her und ersetzt dabei alle Membervariablen und den Path durch das gespeicherte Abbild.
restore
nicht zurückgesetzt wird. Zeichnungen, die seit dem letzten Aufrufen von save
getätigt wurden, bleiben demnach erhalten.clip
-
clip()
: Verwendet den aktuellen Path um den Zeichenbereich einzuschränken. Nach Verwendung vonclip
zeichnen alle Funktionen, die etwas auf dem Canvas-Element ausgeben (inklusiveclearRect
) nur noch in den Bereichen, die sich innerhalb des Path-Objekts befinden, so wie es zum Aufrufzeitpunkt beschaffen war. Dabei liegt ein Punkt innerhalb, wenn er beim Aufrufen vonfill()
mit Farbe ausgefüllt würde. Alle anderen Path-Funktionen sind von dieser Einschränkung nicht betroffen.
isPointInPath
-
isPointInPath(x, y)
: Prüft, ob der angegebene Punkt innerhalb des aktuellen Paths liegt. Die Bedingung hierfür ist dabei dieselbe wie beiclip
.
Anwendungsbeispiel
function zeichne() {
var element = document.getElementById('canvas');
if(element.getContext) {
var context = element.getContext('2d');
context.clearRect(0, 0, element.width, element.height);
context.beginPath();
context.moveTo(20, 80);
context.lineTo(20, 20);
context.arc(90, 50, 30, Math.PI * 7 / 6, Math.PI * 5 / 6);
context.closePath();
context.strokeStyle = '#000000';
context.lineWidth = 5;
context.lineJoin = 'round';
context.stroke();
}
}
In diesem Beispiel werden mithilfe der Path-Funktionen die Umrisse eines Fisches gezeichnet. Dazu wird das Canvas-Element zuerst geleert, indem clearRect
mit den Ausmaßen desselben aufgerufen wird. Außerdem sorgt der darauf folgende Befehl beginPath()
dafür, dass alte Path-Informationen (sofern vorhanden) gelöscht werden. Sobald dies geschehen ist, kann der Referenzpunkt durch Aufrufen der Funktion moveTo
an das untere Ende der Schwanzflosse gesetzt werden. Als Nächstes folgt die Zeichnung dieser, indem mit lineTo
eine Linie zum oberen Punkt der Flosse gezogen wird. Daraufhin sorgt ein Aufruf von arc
dafür, dass auch der Rumpf des Fisches entsteht. Hierbei wurden zwei Dinge ausgenutzt: Einerseits kann durch cleveres Verwenden der von arc
gezeichneten Linie unnötige Rechnerei zur Ermittlung der Startposition des Rumpfes vermieden werden, andererseits wurde die Tatsache ausgenutzt (und dies ist neu), dass der letzte Parameter von arc
optional ist und im Falle der Nichtangabe automatisch mit false belegt wird. Dies bedeutet, dass arc
-Funktionsaufrufe ohne letzten Parameter stets in Uhrzeigerichtung gezeichnet werden. Als letzten Teil des Fisches kann nun der untere Bauchbereich gezeichnet werden. Auch hier werden unnötige Code-Verdopplungen durch Abschließen des Paths mithilfe von closePath
vermieden. Schließlich werden noch einige Feinjustierungen an den Membervariablen vorgenommen und der Path mit stroke
gezeichnet. Das späte Auftreten der Membervariablen soll dabei verdeutlichen, dass lediglich der Zustand dieser zum Aufrufzeitpunkt der Funktion stroke
von Bedeutung ist, nicht der beim Erstellen des Paths.
Weblinks
- W3C: Drawing paths to the canvas
- WHATWG: canvas-Element
- WHATWG: canvasPath
Generatoren: