Pfade
Das <path>-Element ist das leistungsstärkste Element in der SVG-Bibliothek der Grundformen. Es kann verwendet werden, um Linien, Kurven, Bögen und mehr zu erstellen.
Pfad-Elemente erzeugen komplexe Formen durch die Kombination mehrerer gerader oder gebogener Linien. Komplexe Formen, die nur aus geraden Linien bestehen, können auch als <polyline>-Elemente erstellt werden. Obwohl <polyline>- und <path>-Elemente ähnliche Formen erzeugen können, erfordern <polyline>-Elemente viele kleine Linien, um Kurven zu simulieren und skalieren schlecht auf größere Größen.
Ein gutes Verständnis von Pfaden ist wichtig, wenn SVGs erstellt werden. Auch wenn es nicht empfehlenswert ist, komplexe Pfade mit einem XML- oder Texteditor zu schreiben, ermöglicht es das Verständnis ihrer Funktionsweise, Darstellungsprobleme in SVGs zu identifizieren und zu beheben.
Die Form eines <path>-Elements wird durch einen Parameter definiert: d. (Weitere Informationen finden Sie unter Grundformen.) Der d-Attribut enthält eine Reihe von Befehlen und Parameter, die von diesen Befehlen verwendet werden.
Jeder der Befehle wird durch einen spezifischen Buchstaben instanziiert (zum Beispiel das Erstellen einer Klasse, das Benennen und Lokalisieren). Beispielsweise wird der "Move to"-Befehl mit dem Buchstaben M aufgerufen – um zu (10, 10) zu bewegen, würden Sie Ihren Befehl mit M 10 10 beginnen. Wenn der Parser auf diesen Buchstaben stößt, weiß er, dass er zuerst zu einem Punkt gehen muss (ohne eine verbindende Linie zu zeichnen).
Alle Befehle gibt es auch in zwei Varianten. Ein Großbuchstabe gibt absolute Koordinaten auf der Seite an, und ein Kleinbuchstabe gibt relative Koordinaten an (z.B. 10px nach oben und 7px nach links vom letzten Punkt bewegen).
Koordinaten im d-Parameter sind immer einheitslos und daher im Benutzerkoordinatensystem. Später werden wir lernen, wie Pfade transformiert werden können, um anderen Anforderungen gerecht zu werden.
Linienbefehle
Es gibt fünf Linienbefehle für <path>-Knoten. Der erste Befehl ist der "Move To" oder M, der oben beschrieben wurde. Er benötigt mindestens zwei Parameter, beginnend mit einer x- und y-Koordinate, zu der bewegt werden soll. Wenn sich der Cursor bereits an einem Punkt auf der Seite befindet, wird keine Linie gezeichnet, die die beiden Positionen verbindet. Der "Move To"-Befehl erscheint am Anfang von Pfaden, um anzugeben, wo das Zeichnen beginnen soll. Zum Beispiel:
M x y (or) m dx dy
Nach einem "Move To"-Befehl kann mehr als ein Koordinatenpaar folgen. Nur das erste Paar bewegt den Cursor; jedes Paar danach zeichnet eine Linie, genau wie ein "Line To"-Befehl verwendet worden wäre. So ist M 10 10 90 10 90 90 gleichbedeutend mit M 10 10 L 90 10 L 90 90. Paare, die auf m folgen, zeichnen Linien relativ zur aktuellen Position, auf die gleiche Weise.
Zum Beispiel verwendet dieser Pfad einen einzigen M-Befehl mit drei Koordinatenpaaren, um zwei verbundene Liniensegmente zu zeichnen:
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M10 10 90 10 90 90" stroke="black" fill="none" />
</svg>
Im folgenden Beispiel gibt es nur einen Punkt bei (10, 10). Beachten Sie jedoch, dass er nicht sichtbar wäre, wenn ein Pfad einfach normal gezeichnet würde. Zum Beispiel:
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M10 10" />
</svg>
Es gibt drei Befehle, die Linien zeichnen. Der generischste ist der "Line To"-Befehl, aufgerufen mit L. L nimmt zwei Parameter an – x- und y-Koordinaten – und zeichnet eine Linie von der aktuellen Position zu einer neuen Position.
L x y (or) l dx dy
Es gibt zwei abgekürzte Formen zum Zeichnen horizontaler und vertikaler Linien. H zeichnet eine horizontale Linie, und V zeichnet eine vertikale Linie. Beide Befehle nehmen nur einen Parameter an, da sie nur in eine Richtung bewegen.
H x (or) h dx V y (or) v dy
Ein einfacher Ausgangspunkt ist das Zeichnen einer Form. Wir beginnen mit einem Rechteck (der gleiche Typ, der auch einfacher mit einem <rect>-Element erstellt werden könnte). Es besteht nur aus horizontalen und vertikalen Linien.
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 10 H 90 V 90 H 10 L 10 10" />
</svg>
Wir können die obige Pfaderklärung ein wenig verkürzen, indem wir den "Close Path"-Befehl verwenden, aufgerufen mit Z. Dieser Befehl zeichnet eine gerade Linie von der aktuellen Position zurück zu dem ersten nicht geschlossenen Punkt (erster Punkt nach dem letzten Z-Befehl, wenn es einen gibt, oder der erste Punkt im Pfad sonst) und schließt den Pfad mit einer Linienverbindung ab. Er ist oft am Ende eines Pfadknotens platziert, obwohl nicht immer. Es gibt keinen Unterschied zwischen dem Groß- und Kleinbuchstabenbefehl.
Z (or) z
So könnte unser oben stehender Pfad auf folgenden verkürzt werden:
<path d="M 10 10 H 90 V 90 H 10 Z" fill="none" stroke="black" />
Die relativen Formen dieser Befehle können ebenfalls verwendet werden, um das gleiche Bild zu zeichnen. Relative Befehle werden durch die Verwendung von Kleinbuchstaben aufgerufen, und anstatt den Cursor zu einer genauen Koordinate zu bewegen, bewegt er sich relativ zu seiner letzten Position. Zum Beispiel könnte das <path>-Element, da unser Rechteck 80×80 groß ist, so geschrieben werden:
<path d="M 10 10 h 80 v 80 h -80 Z" fill="none" stroke="black" />
Der Pfad bewegt sich zum Punkt (10, 10) und dann horizontal 80 Punkte nach rechts, dann 80 Punkte nach unten, dann 80 Punkte nach links und dann zurück zum Anfang.
In diesen Beispielen wäre es wahrscheinlich intuitiver, die <polygon>- oder <polyline>-Elemente zu verwenden. Pfade werden jedoch so häufig beim Zeichnen von SVG verwendet, dass Entwickler sie möglicherweise bevorzugen. Es gibt keinen wirklichen Leistungsnachteil oder -vorteil, wenn eine der beiden Optionen verwendet wird.
Kurvenbefehle
Es gibt drei verschiedene Befehle, die zur Erstellung glatter Kurven verwendet werden können. Zwei dieser Kurven sind Bézierkurven, und die dritte ist ein "Arc" oder Teil eines Kreises. Möglicherweise haben Sie bereits praktische Erfahrungen mit Bézierkurven bei der Verwendung von Pfadwerkzeugen in Inkscape, Illustrator oder Photoshop gesammelt. Es gibt eine unendliche Anzahl von Bézierkurven, aber nur zwei sind in <path>-Elementen verfügbar: eine kubische, aufgerufen mit C, und eine quadratische, aufgerufen mit Q.
Bézier-Kurven
Die kubische Kurve, angesprochen mit C, ist die etwas komplexere Kurve. Kubische Béziers erfordern zwei Kontrollpunkte für jeden Punkt. Um eine kubische Bézier zu erstellen, müssen daher drei Koordinatensätze angegeben werden.
C x1 y1, x2 y2, x y (or) c dx1 dy1, dx2 dy2, dx dy
Der letzte Koordinatensatz hier (x, y) gibt an, wo die Linie enden soll. Die anderen beiden sind Kontrollpunkte. (x1, y1) ist der Kontrollpunkt für den Start der Kurve, und (x2, y2) ist der Kontrollpunkt für das Ende. Die Kontrollpunkte beschreiben im Wesentlichen die Steigung der Linie, die an jedem Punkt beginnt. Die Bézier-Funktion erzeugt dann eine glatte Kurve, die von der zu Beginn der Linie festgelegten Steigung zur Steigung am anderen Ende übergeht.
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 10 C 20 20, 40 20, 50 10" stroke="black" fill="none" />
<path d="M 70 10 C 70 20, 110 20, 110 10" stroke="black" fill="none" />
<path d="M 130 10 C 120 20, 180 20, 170 10" stroke="black" fill="none" />
<path d="M 10 60 C 20 80, 40 80, 50 60" stroke="black" fill="none" />
<path d="M 70 60 C 70 80, 110 80, 110 60" stroke="black" fill="none" />
<path d="M 130 60 C 120 80, 180 80, 170 60" stroke="black" fill="none" />
<path d="M 10 110 C 20 140, 40 140, 50 110" stroke="black" fill="none" />
<path d="M 70 110 C 70 140, 110 140, 110 110" stroke="black" fill="none" />
<path d="M 130 110 C 120 140, 180 140, 170 110" stroke="black" fill="none" />
</svg>
Das obige Beispiel erzeugt neun kubische Bézierkurven. Während sich die Kurven nach rechts bewegen, werden die Kontrollpunkte horizontal verteilt. Während sich die Kurven nach unten bewegen, werden sie weiter von den Endpunkten getrennt. Hierbei ist zu beachten, dass die Kurve in Richtung des ersten Kontrollpunktes beginnt und dann gebogen wird, so dass sie entlang der Richtung des zweiten Kontrollpunktes ankommt.
Mehrere Bézierkurven können miteinander verbunden werden, um erweiterte, glatte Formen zu erzeugen. Oft ist der Kontrollpunkt auf einer Seite eines Punktes eine Spiegelung des Kontrollpunktes, der auf der anderen Seite verwendet wird, um die Steigung konstant zu halten. In diesem Fall kann eine Abkürzungsversion der kubischen Bézier verwendet werden, die durch den Befehl S (oder s) bezeichnet wird.
S x2 y2, x y (or) s dx2 dy2, dx dy
S erzeugt denselben Kurventyp wie zuvor – aber wenn es einem anderen S-Befehl oder einem C-Befehl folgt, wird der erste Kontrollpunkt als Spiegelung des zuvor verwendeten angenommen. Wenn der S-Befehl keinem anderen S- oder C-Befehl folgt, wird die aktuelle Position des Cursors als erster Kontrollpunkt verwendet. Das Ergebnis ist nicht dasselbe wie das, was der Q-Befehl mit denselben Parametern erzeugt hätte, aber es ist ähnlich.
Ein Beispiel für diese Syntax wird unten gezeigt, und in der Abbildung links sind die angegebenen Kontrollpunkte in Rot und der abgeleitete Kontrollpunkt in Blau dargestellt.
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<path
d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"
stroke="black"
fill="none" />
</svg>
Der andere Typ von Bézierkurve, die quadratische Kurve, aufgerufen mit Q, ist tatsächlich eine einfachere Kurve als die kubische. Sie erfordert einen Kontrollpunkt, der die Steigung der Kurve sowohl am Startpunkt als auch am Endpunkt bestimmt. Sie nimmt zwei Parameter an: den Kontrollpunkt und den Endpunkt der Kurve.
Hinweis:
Die Koordinaten-Deltas für q sind beide relativ zum vorherigen Punkt (d.h. dx und dy sind nicht relativ zu dx1 und dy1).
Q x1 y1, x y (or) q dx1 dy1, dx dy
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 80 Q 95 10 180 80" stroke="black" fill="none" />
</svg>
Wie bei der kubischen Bézierkurve gibt es auch eine Abkürzung, um mehrere quadratische Béziers aneinanderzureihen, aufgerufen mit T.
T x y (or) t dx dy
Diese Abkürzung betrachtet den zuvor verwendeten Kontrollpunkt und leitet einen neuen davon ab. Dies bedeutet, dass nach dem ersten Kontrollpunkt ziemlich komplexe Formen erstellt werden können, indem nur Endpunkte angegeben werden.
Dies funktioniert nur, wenn der vorherige Befehl ein Q- oder T-Befehl war. Wenn nicht, wird der Kontrollpunkt als identisch mit dem vorherigen Punkt angenommen, und es werden nur Linien gezeichnet.
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 80 Q 52.5 10, 95 80 T 180 80" stroke="black" fill="none" />
</svg>
Beide Kurven erzeugen ähnliche Ergebnisse, obwohl die kubische mehr Freiheit bzgl. des exakten Aussehens der Kurve bietet. Zu entscheiden, welche Kurve verwendet werden soll, ist situationsabhängig und hängt von der Symmetrie der Linie ab.
Bögen
Der andere Typ von gebogenen Linien, die mit SVG erstellt werden können, ist der Bogen, aufgerufen mit dem A-Befehl. Bögen sind Abschnitte von Kreisen oder Ellipsen.
Für einen gegebenen Radius auf der x- und y-Achse gibt es zwei Ellipsen, die zwei beliebige Punkte verbinden können (solange sie sich innerhalb des Kreisradius befinden). Auf einer dieser Kreise gibt es zwei mögliche Pfade, um die Punkte zu verbinden – in jeder Situation gibt es also vier mögliche Bögen.
Aufgrund dessen erfordern Bögen viele Parameter:
A rx ry x-axis-rotation large-arc-flag sweep-flag x y a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy
Zu Beginn nimmt das Bogenelement zwei Parameter für den x- und y-Radius an. Bei Bedarf siehe <ellipse>s und deren Verhalten. Die letzten beiden Parameter geben die x- und y-Koordinaten an, um den Strich zu beenden. Zusammen definieren diese vier Werte die grundlegende Struktur des Bogens.
Der dritte Parameter beschreibt die Drehung des Bogens. Dies lässt sich am besten mit einem Beispiel erklären:
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg">
<path
d="M 10 315
L 110 215
A 30 50 0 0 1 162.55 162.45
L 172.55 152.45
A 30 50 -45 0 1 215.1 109.9
L 315 10"
stroke="black"
fill="green"
stroke-width="2"
fill-opacity="0.5" />
</svg>
Das Beispiel zeigt ein <path>-Element, das sich diagonal über die Seite zieht. In der Mitte wurden zwei elliptische Bögen ausgeschnitten (x-Radius = 30, y-Radius = 50). Beim ersten wurde die x-axis-rotation auf 0 belassen, sodass die Ellipse, um die der Bogen verläuft (in Grau dargestellt), senkrecht orientiert ist. Für den zweiten Bogen wurde jedoch die x-axis-rotation auf -45 Grad gesetzt. Dies dreht die Ellipse so, dass sie mit ihrer Nebenachse entlang der Pfadrichtung ausgerichtet ist, wie durch die zweite Ellipse im Beispielbild gezeigt.
Für die ungedrehte Ellipse im obigen Bild gibt es nur zwei verschiedene Bögen und nicht vier zur Auswahl, weil die Linie vom Start- bis zum Endpunkt durch das Zentrum der Ellipse verläuft. In einem leicht modifizierten Beispiel sind die zwei Ellipsen, die die vier verschiedenen Bögen bilden, zu sehen:
<svg xmlns="http://www.w3.org/2000/svg" width="320" height="320">
<path
d="M 10 315
L 110 215
A 36 60 0 0 1 150.71 170.29
L 172.55 152.45
A 30 50 -45 0 1 215.1 109.9
L 315 10"
stroke="black"
fill="green"
stroke-width="2"
fill-opacity="0.5" />
</svg>
Beachten Sie, dass jede der blauen Ellipsen von zwei Bögen gebildet wird, je nachdem, ob sie im Uhrzeigersinn oder gegen den Uhrzeigersinn verläuft. Jede Ellipse hat einen kurzen und einen langen Bogen. Die zwei Ellipsen sind nur Spiegelbilder voneinander. Sie sind entlang der Linie gebildet von den Start- und Endpunkten gespiegelt.
Wenn die Start-End-Punkte weiter auseinander liegen, als der x- und y-Radius der Ellipse erreichen kann, werden die Ellipsenradien so minimal erweitert, dass sie die Start-End-Punkte erreichen können. Das interaktive Codepen am Ende dieser Seite demonstriert dies gut. Um zu bestimmen, ob die Radien einer Ellipse groß genug sind, um eine Erweiterung zu erfordern, müsste ein System von Gleichungen gelöst werden, wie zum Beispiel dieses auf Wolfram Alpha. Diese Berechnung ist für die ungedrehte Ellipse mit Start-End (110, 215)→(150.71, 170.29). Die Lösung (x, y) ist das Zentrum der Ellipse(n). Die Lösung wird imaginary sein, wenn die Radien der Ellipse zu klein sind. Diese zweite Berechnung ist für die ungedrehte Ellipse mit Start-End (110, 215)→(162.55, 162.45). Die Lösung hat eine kleine imaginäre Komponente, weil die Ellipse gerade so erweitert wurde.
Die oben genannten vier verschiedenen Wege werden durch die nächsten zwei Parameter-Flags bestimmt. Wie bereits erwähnt, gibt es noch zwei mögliche Ellipsen, um den Pfad zu umrunden, und zwei verschiedene mögliche Pfade auf beiden Ellipsen, wodurch vier mögliche Pfade entstehen. Der erste Parameter ist das large-arc-flag. Es bestimmt, ob der Bogen größer oder kleiner als 180 Grad sein soll; letztlich bestimmt dieses Flag, in welcher Richtung der Bogen um einen gegebenen Kreis verlaufen wird. Der zweite Parameter ist das sweep-flag. Es bestimmt, ob der Bogen in positive oder negative Winkel verlaufen soll, was im Wesentlichen bestimmt, welcher der beiden Kreise umrundet wird. Das untenstehende Beispiel zeigt alle vier möglichen Kombinationen sowie die zwei Kreise für jeden Fall.
<svg width="360" height="360" xmlns="http://www.w3.org/2000/svg">
<path
d="M 100 100
A 45 45, 0, 0, 0, 145 145
L 145 100 Z"
fill="#00FF00A0"
stroke="black"
stroke-width="2" />
<path
d="M 250 100
A 45 45, 0, 1, 0, 295 145
L 295 100 Z"
fill="#FF0000A0"
stroke="black"
stroke-width="2" />
<path
d="M 100 250
A 45 45, 0, 0, 1, 145 295
L 145 250 Z"
fill="#FF00FFA0"
stroke="black"
stroke-width="2" />
<path
d="M 250 250
A 45 45, 0, 1, 1, 295 295
L 295 250 Z"
fill="#0000FFA0"
stroke="black"
stroke-width="2" />
<path
d="M 45 45 L 345 45 L 345 345 L 45 345 Z M 195 45 L 195 345 M 45 195 L 345 195"
fill="none"
stroke="black" />
<text x="140" y="20" font-size="20" fill="black">Large arc flag</text>
<text
x="-15"
y="195"
font-size="20"
fill="black"
transform="rotate(-90)"
transform-origin="20 195">
Sweep flag
</text>
<text x="120" y="40" font-size="20" fill="black">0</text>
<text x="270" y="40" font-size="20" fill="black">1</text>
<text x="30" y="120" font-size="20" fill="black">0</text>
<text x="30" y="270" font-size="20" fill="black">1</text>
</svg>
Bögen sind eine einfache Möglichkeit, Kreisbögen oder Ellipsen in Zeichnungen zu erstellen. Zum Beispiel würde ein Tortendiagramm für jedes Stück einen anderen Bogen erfordern.
Wenn Sie von <canvas> zu SVG wechseln, können Bögen am schwierigsten zu erlernen sein, sind aber auch weitaus leistungsfähiger. Vollständige Kreise und Ellipsen sind die einzigen Formen, bei denen SVG-Bögen Schwierigkeiten haben. Da die Start- und Endpunkte für einen jeglichen Pfad um einen Kreis derselbe Punkt sind, gäbe es unendlich viele Kreise, die gewählt werden könnten, und der eigentliche Pfad ist undefiniert. Es ist möglich, sie zu approximieren, indem die Start- und Endpunkte des Pfades leicht abweichen, und sie dann durch ein weiteres Pfadsegment verbunden werden. Zum Beispiel ist es möglich, einen Kreis mit einem Bogen für jede Halbkugel zu erstellen. Zu diesem Zeitpunkt ist es oft einfacher, einen richtigen <circle> oder <ellipse>-Knoten zu verwenden. Dieses interaktive Demo könnte helfen, die Konzepte hinter SVG-Bögen zu verstehen.