SVG/Tutorials/Pfade

Aus SELFHTML-Wiki
< SVG‎ | Tutorials(Weitergeleitet von Bearing)
Wechseln zu: Navigation, Suche

Neben den im vorigen Kapitel erwähnten Grundformen gibt es noch das Pfad-Objekt. Dieses besteht aus mehreren (Knoten)-Punkten, die durch gerade und gebogene Linien zu komplexen Formen verbunden werden. Pfade können offen oder geschlossen sein und dann gefüllt oder mit Randlinien versehen werden.

SELF-Logo mit sichtbaren Knotenpunkten

Das path-Element ermöglicht es mit solchen Linien, Bögen und Kurven Pfad-Objekte als Grafik-Objekte, Animationsstrecken oder Maskenregionen zu erzeugen. Analog zu den Polygonen werden Punkte festgelegt[1], von denen dann bestimmte Pfadkommandos zeichnen.

Dieses Tutorial erklärt die einzelnen Pfadkommandos, mit denen du beliebige Pfade zusammenstellen kannst. Dabei fangen wir bei einfachen Linien an und gehen schrittweise zu komplexeren Figuren über. In der Praxis wird man Pfade mit Generatoren und Grafikprogrammen erstellen, trotzdem ist es nützlich zu wissen, wie sie aufgebaut sind.

Linien

MoveTo

Mit dem MoveTo-Befehl kannst du einen Ausgangspunkt festlegen, an dem der gedachte Zeichenstift auf die „Leinwand“ gesetzt wird.[2] Die erste Angabe in einem d-Attribut muss ein MoveTo-Befehl sein, wobei m als M interpretiert wird.

Schreibt man hinter einen MoveTo-Befehl mehr als einen Punkt, werden sie mit einer Linie verbunden, als ob man den LineTo-Befehl verwendet hätte. In dem Fall ist die Groß- und Kleinschreibung des MoveTo-Befehls auch dann relevant, wenn er der erste Befehl des d-Attributs ist, weil die Groß- und Kleinschreibung auf den versteckten LineTo-Befehl übertragen wird.

Kommando Name Parameter Beschreibung
M x,y moveTo x,y-Koordinaten setzt den aktuellen Punkt fest, von dem aus der Pfad starten soll.
(Ausgangspunkt ist der Ursprung des Koordinatensystems)
m x,y moveTo x,y-Koordinaten setzt den aktuellen Punkt fest, von dem aus der Pfad starten soll.
(Ausgangspunkt ist die letzte festgelegte Koordinate bzw. im Falle von z als letztem Befehl die Koordinaten des letzten MoveTo-Befehls)

LineTo

Mit LineTo kannst du nun Linien zeichnen.[3]

Kommando Name Parameter Beschreibung
L x,y (absolut) LineTo x,y-Koordinaten zeichnet eine Linie vom aktuellen zum angegebenen Punkt.
l x,y (relativ) LineTo x,y-Koordinaten zeichnet eine Linie vom aktuellen Punkt in diese Richtung.
Stift setzen, Linien zeichnen ansehen …
<svg>
  <path d="M 50,50  100,100 M100,50 150,100" stroke="gold" />
  <path d="m250,50 l100,100 m0,-100 l 100,100 l100,-100" stroke="red" />
</svg>

Im Beispiel gibt es zwei Pfade:

  1. Der „goldene“ Pfad besteht aus folgenden absoluten Pfad-Kommandos:
    1. M 50,50 setzt den Stift auf (50|50)
    2. 100,100 zieht eine Linie zu (100|100) - ohne Pfad-Kommando wird der LineTo-Befehl verwendet.
    3. M100,50 nimmt den Stift hoch und setzt ihn bei (100|50) neu an.
    4. 100,100 zieht eine Linie zu (150|100)
  2. Der „rote“ Pfad besteht aus folgenden relativen Pfad-Kommandos:
    1. M250,50 setzt den Stift auf (250|50)
    2. l 100,100 zieht eine Linie 100 Einheiten nach rechts und 100 Einheiten nach unten
    3. M0,-100 nimmt den Stift hoch und setzt ihn 100 Einheiten höher neu an.
    4. l 100,100 zieht eine Linie je 100 Einheiten nach rechts und unten
    5. l100,-100 zieht eine Linie je 100 Einheiten nach rechts und oben

Verändere die Werte für den ersten MoveTo-Befehl und beobachte, wie sich die beiden Pfade verhalten!

Empfehlung: Verwende relative Pfad-Kommandos!
So kannst du Deine Pfade später gegebenenfalls mit nur einer Änderung verschieben.
Lea Verou hat ein Tool entwickelt, mit dem absolute in relative Kommandos umgewandelt werden können:
Convert SVG path to all-relative or all-absolute[4]

Warum sind „rot“ und „golden“ in Anführungszeichen notiert? - Ein Pfad-Objekt ist erst einmal nur ein unsichtbarer Pfad. Wie man ihm sichtbar machen kann, erfährst du gleich!

Wie man die einzelnen Knotenpunkte der Pfade sichtbar machen kann, erfährst du im Kapitel über Markierungen.

Pfadkommandos - die beste Schreibweise?

Im der Spec werden verschiedene Schreibweisen genannt. Es ist möglich zwischen Pfadkommando und Werten, sowie den beiden Koordinaten ein Leerzeichen zu notieren (oder dies bei negativen Werten wegzulassen). Bei umfangreicheren Pfaden verliert man so schnell die Zuordnung. [5]
Dieser Beispiel-Pfad aus der Spec zeigt die von uns bevorzugte Schreibweise[6]:

<path class="SamplePath" d="M100,200 C100,100 250,100 250,200 S400,300 400,200" />

Kein Leerzeichen zwischen Kommando und Koordinaten; Koordinaten durch ein Komma getrennt, damit die Zuordnung klar ist.

horizontale und vertikale Linien

Wenn du Linien nur waagerecht oder senkrecht führen willst, kannst du die Befehle HorizontalLineto und VerticalLineTo verwenden.


Kommando Name Parameter Beschreibung
H x (absolut) Horizontal LineTo x-Koordinate
(y bleibt gleich)
zeichnet vom aktuellen Punkt aus eine horizontale Linie, die aber vom Ursprung ausgehend berechnet wird.
h x (relativ) Horizontal LineTo x-Koordinate
(y bleibt gleich)
zeichnet vom aktuellen Punkt aus eine horizontale Linie mit der angegebenen Länge.
V y (absolut) Vertical LineTo y-Koordinate
(x bleibt gleich)
zeichnet vom aktuellen Punkt aus eine vertikale Linie, die aber vom Ursprung ausgehend berechnet wird.
v y (relativ) Vertical LineTo y-Koordinate
(x bleibt gleich)
zeichnet vom aktuellen Punkt aus eine vertikale Linie mit der angegebenen Länge.


Linien horizontal, vertikal und überallhin ansehen …
	<path d="M50,50 H100" stroke="blue" />
	<path d="M50,50 L100,100" stroke="red" />
	<path d="M50,50 V100" stroke="gold" />
	<path d="M50,150 l100,100" stroke="red" />
	<path d="M50,150 h100" stroke="blue" />
	<path d="M50,150 v100" stroke="gold" />

Wie du bei der oberen Liniengruppe sehen kannst, führen die absoluten Befehle L, H und V zu unerwarteten Ergebnissen. Die Linien führen zu den absoluten Koordinaten, sodass die Linien hier viel kürzer sind.

Eine Verschiebung des Startpunktes mit m 100,100 würde sowohl den H 100- als auch den V 100-Befehl völlig aufheben.

Schließen von Formen

Mit dem closePath-Befehl Z kannst du Pfade schließen, indem du den Pfad zu seinem Anfangspunkt zurückführst. Dieser Ausgangspunkt ist der Punkt, den du mit dem zuletzt verwendeten M-Befehl gesetzt hast. Somit spricht nichts gegen die Verwendung mehrerer Z-Befehle in einem Pfad. Die Groß- und Kleinschreibung des Befehls wird ignoriert.

Schließen von Pfaden ansehen …
<svg>
  <path d="M 10,110 l40,-80 l40,80" />
  <path d="M150,110 v-80 h80 v80" />
  <path d="M300,110 l-15,-50 l40,-30 l40,30 l-15,50" />
  <path d="M420,110 l-20,-40 l20,-40 h50 l20,40 l-20,40" />
	
  <path d="M 10,250 l40,-80 l40,80 z" />
  <path d="M150,250 v-80 h80 v80 z" />
  <path d="M300,250 l-15,-50 l40,-30 l40,30 l-15,50 z" />
  <path d="M420,250 l-20,-40 l20,-40 h50 l20,40 l-20,40 z />
</svg>

Die obere Reihe besteht aus Pfaden, die nicht geschlossen sind. Trotzdem werden sie, wenn man eine Füllung festlegt, als Vielecke dargestellt. Nur der Rand umschließt die Vielecke nicht.

Die untere Reihe besteht aus Pfaden, die mit z geschlossen wurden, sodass der Rand umlaufend ist.

Dabei wird auch deutlich, dass unser Pfad eben nicht nur eine Kette von Linien ist, sondern ein zweidimensionales Objekt umschließt. Durch eine Füllung mit dem fill-Präsentationsattribut kann dies sichtbar gemacht werden.

Die Randlinie des Pfads kann mit dem stroke-Präsentationsattribut eingefärbt werden.

Verändere die stroke-width im Beispiel auf 10 oder 14. Du siehst, dass die Randlinie mittig auf der Pfadlinie liegt und nach innen und außen wächst.

Hauptartikel: SVG/Farben

Bézier-Kurven

quadratische Bézier-Kurven

Mit dem Quadratic Bézier CurveTo-Befehl Q kannst du quadratische Bézier-Kurven erstellen. Dies sind Kurven zwischen zwei Punkten, die durch einen Kontrollpunkt beeinflusst werden.[7]

Kommando Name Parameter Beschreibung
Q (absolut)
q (relativ)
Quadratic Bézier CurveTo (x1 y1 x y)+ zeichnet eine quadratische Bézier-Kurve mit dem Kontrollpunkt (x1,y1).
T (absolut)
t (relativ)
Shorthand/Smooth Quadratic Bézier CurveTo (x y)+ ähnlich dem Kommando Q, jedoch wird hier als Kontrollpunkt die Punktspiegelung des Kontrollpunktes aus der direkt zuvor festgelegten quadratischen Bézier-Kurve an deren Endpunkt verwendet (war der direkt vorhergehende Befehl keine quadratische Bézier-Kurve, wird der aktuelle Endpunkt als Kontrollpunkt verwendet, S ist dann identisch zu L).


Pfade mit quadratischen Bézier-Kurven ansehen …
Sinuswelle mit q und t ansehen …
<path d="M50,200 q100,-100 200,0 t200,0 t200,0 t200,0"/>

In diesem Beispiel wird eine quadratische Bézier-Kurve mit dem Kommando q gezeichnet und mit t 200,0 drei mal verlängert. Als Kontrollpunkt wird die Punktspiegelung des Kontrollpunktes aus der direkt zuvor festgelegten quadratischen Bézier-Kurve an deren Endpunkt verwendet. So entsteht eine regelmäßige Wellenlinie mit nur wenigen Kommandos.

kubische Bézier-Kurven

Mit dem CurveTo-Befehl kannst du kubische Bézier-Kurven erstellen. Dies sind Kurven zwischen zwei Punkten, die durch zwei Kontrollpunkte beeinflusst werden.[8]

Kommando Name Parameter Beschreibung
C (absolut)
c (relativ)
CurveTo (x1,y1  x2,y2  x,y) zeichnet vom aktuellen Punkt aus eine kubische Bézier-Kurve zum Endpukt (x,y). Die Kurve benötigt 2 Kontrollpunkte (x1,y1) und (x2,y2).
S (absolut)
s (relativ)
Shorthand/Smooth CurveTo (x2,y2  x,y)+ ähnlich dem Kommando C, jedoch wird hier als erster Kontrollpunkt die Punktspiegelung des letzten aus der direkt zuvor festgelegten kubischen Bézier-Kurve an deren Endpunkt verwendet (war der direkt vorhergehende Befehl keine kubische Bézier-Kurve, wird der aktuelle Endpunkt als Kontrollpunkt verwendet).
Beispiel ansehen …
	<path d="M100,150 c100,-140 200,140 300,0" stroke="blue" />
	<path d="M500,150 c0,-140 300,-140 300,0" stroke="gold" />
	<path d="M100,550 c200,-200 -90,-260 300,0" stroke="red" />
	<path d="M500,550 c300,-250 -100,-260 300,0" stroke="lime" />

Bei den Punkten Startpunkt A und Endpunkt D handelt es sich um den Start- und den Endpunkt der Kurve. Der Startpunkt wird im d-Attribut durch Mx,y der Endpunkt durch die letzten beiden Koordinaten 400,150 beschrieben. Durch die hier zusätzlich eingezeichneten Kontroll- oder Ablenkungspunkte Kontrollpunkt B und Kontrollpunkt C wird die Richtung der Kurve bestimmt. Die Krümmung wird umso stärker, je weiter sich die Ablenkungspunkte von den Ursprungspunkten entfernen und schwächer, wenn sie sich ihnen nähern. Es sei darauf hingewiesen, dass die Kurve niemals durch diese beiden Punkte verlaufen kann.

Beachte: In den hier verwendeten Codebeispielen wurden die einzelnen Werte durch Kommata zu Koordinaten formatiert. Ebenso richtig wäre die Darstellung <path d="M 100 150 C 200 10 300 290 400 150"/>, in der alle Werte nur durch Leerzeichen getrennt sind.
Siehe: [[#Pfadkommandos - die beste Schreibweise}|Pfadkommandos - die beste Schreibweise}?]]

Weitere Beispiele findest du im MDN[9].

Empfehlung: Verwende zum Erstellen komplexer Pfade einen SVG-Editor, der dir viel Arbeit abnehmen kann.

elliptische Bögen

Mit dem Kommando A, bzw. a können elliptische Bögen gezeichnet werden. Wenn du gleiche Werte für die Radien nimmst, erzeugst du einen Kreisbogen. Darüber hinaus muss noch festgelegt werden, welcher der bei gegebenen Radien und gegebener Achslage noch vier möglichen Bögen gezeichnet werden soll.

Selbst das W3C hält die derzeitige Syntax für nicht optimal.

Kommando Name Parameter Beschreibung
A rx,ry,phi lf sf x,y elliptische Kurve
  • rx,ry phi
  • lf sf
  • x,y
zeichnet vom aktuellen Punkt aus einen elliptischen Bogen. Größe und Lage der dem Bogen zugrundeliegenden Ellipse werden durch die zwei Halbachsen[10] (rx, ry) und den Neigungswinkel phi der x-Achse festgelegt. Der Mittelpunkt (cx, cy) der Ellipse wird intern automatisch berechnet. lf=large-arc-flag und sf=sweep-flag legen die Richtung des Bogens fest.
Die vier Möglichkeiten, bei gleichem Wert für rx, ry, phi, x und y einen Bogen vom oberen zum unteren Punkt zu zeichnen:
rot: lf=0 und sf=0;
grün: lf=0 und sf=1;
blau: lf=1 und sf=0;
gold: lf=1 und sf=1;

Folgende Angaben sind nötig:

  • Der Bogen startet am (vorher festgelegten) aktuellen Punkt.
  • x, y: Endpunkt
  • rx, ry: Radien (eigentlich: Halbachsen)
  • phi: Die +X-Halbachse der Ellipse wird durch phi relativ zum Koordinatensystem gedreht.

Mit diesen Angaben können vier verschiedene Bögen gezeichnet werden. lf = large-arc-flag und sf = sweep-flag legen daher die Richtung des Bogens fest[11]:

  • Das large-arc-flag legt fest, ob
    • mit large-arc-flag:1 ein größerer (mehr als 180 Grad) oder
    • mit large-arc-flag:0 ein kleinerer Bogen (weniger als 180 Grad) gezeichnet wird.
  • Das sweep-flag legt fest, ob
    • mit einem sweep-flag:1 der Bogen mit einer positiven Richtung ("Rechtskurve") gezeichnet wird oder
    • mit einem sweep-flag:0 der Bogen mit einer negativen Richtung ("Linkskurve") gezeichnet wird.
elliptische Bögen und Pie Chart ansehen …

Das Beispiel enthält 4 elliptische Bögen:

  • alle Bögen haben
    • jeweils den gleichen Wert a 99,99 0 für die Radien rx und ry und den Drehwinkel phi von Null – beschreiben also einen Kreisbogen (bei dem phi bedeutungslos ist).
    • jeweils den gleichen Endpunkt 0,150 (also 150 Einheiten weiter unten)
  • der blaue mit 1 0 (lf=1 und sf=0) für einen größeren mit negativer Richtung
  • der rote mit 0 0 (lf=0 und sf=0) einen kleineren mit negativer Richtung
  • der grüne mit 0 1 (lf=0 und sf=1) einen kleineren mit positiver Richtung
  • Der goldene mit 1 1 (lf=1 und sf=1) einen größeren mit positiver Richtung
Beachte: Es gibt keine Warnung, wenn es für die angegebenen Werte keine Möglichkeit für eine Ellipse und damit für einen Teil davon gibt. Darauf muss bei manueller Erstellung selbst geachtet werden. Das W3C-Konsortium sieht hier folgendes vor:
  • Startpunkt = Zielpunkt: Kommando wird ignoriert.
  • Einer der Radien ist Null: Gerade Linie zum Zielpunkt.
  • Negativer Radius: Minuszeichen wird ignoriert (Betragsfunktion).
  • Ellipse zu klein, um den Zielpunkt zu erreichen: Ellipse wird proportional vergrößert, bis es genau eine Lösung gibt.
  • Jeder von Null verschiedene Wert für Large-Arc-Flag oder Sweepflag wird als Eins interpretiert (Null = "Nein", sonst "Ja").
Beachte: Wenn du einen vollen 360°-Kreisbogen zeichnen willst, kannst du für den Endpunkt (x,y) nicht die gleichen Werte nehmen wie die Startposition.

Verwende entweder - mit large-arc-flag=1 - einen Endpunkt nahe dem Startpunkt und schließe den Pfad mit z, oder zeichne zwei Teilkreise (z. B. Viertelkreis und Dreiviertelkreis) mit verschiedenen Long-arc-flags:

<path id="vollkreis" d="M 91,181 a 90,90,1 1 1 1,0 z" />
<path id="kreis" d="M 100,100 A 90,90,0 1 1 190,190 A 90,90,0 0 1 100,100 z" />
Hinweis:
Das Zeichnen von Pfaden mit Bögen und Kurven ist nicht intuitiv und verlangt einige Übung. Verwende Pfad-Generatoren, die durch Klicken schnelle Ergebnisse ermöglichen:
  • SVG <path> builder Werte können über Eingabefelder und Checkboxen gesetzt werden.
  • SVG Path Builder (Anthony Dugois) Punkte und Kontrollpunkte können mit der Maus gesetzt und verschoben werden

Selbst das W3C hält die derzeitige Syntax für nicht optimal.

Bogen-Generator für arc-Command ansehen …

Weitere Beispiele findest du im MDN[12] und in der Spec.[13]

Anwendungsbeispiele

Beispiel ansehen …
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -1 202 202">  
<title>SELF-Logo under construction</title>
	<defs>
<style type="text/css">
.gelb{
	fill:	#dfac20;
	stroke-width:	1;
	stroke:	#337599;
}

.blau{
	fill:	#337599;
	stroke: #337599;
    }
 
#bezierkurven path {
  stroke: #c82f04;
	stroke-width: 1;
	fill: none;
}

		
	marker,
marker path {
	fill: white;
	stroke: #337599;
}	
 
</style>
		<marker id="markerAnfang" markerWidth="12" markerHeight="12" refX="6" refY="6">
			<rect x="1" y="1" width="10" height="10" /> </marker>
		<marker id="markerKreis" markerWidth="12" markerHeight="12" refX="6" refY="6">
			<circle cx="6" cy="6" r="5" /> </marker>
		<symbol id="point">
		   <circle cx="5" cy="5" r="4" style="fill:#c82f04; stroke: white;"/>
		</symbol>
	</defs>
  <g id="Logo">
    <path class="gelb" style="marker-start: url(#markerAnfang); marker-mid: url(#markerKreis); marker-end: url(#markerAnfang); "
	        
	      d="M141,195 C164,189 178,173 178,136 C178,87 150,85 111,74 C106,73 86,67 82,64 C81,62 81,60 81,59 C81,46 89,48 100,48 C110,48 120,48 131,49 
	         C138,50 145,51 152,51 C170,51 170,38 170,23 C170,13 168,8 163,5 L183,5 C199,5 195,10 195,169 L195,183 C195,189 189,195 183,195 L141,195 "/>
    <path class="blau" 
	      d="M37,195 L16,195 C10,195 5,189 5,183 L5,16 C5,10 10,5 16,5 L61,5 C39,11 24,26 24,62 C24,75 27,91 37,100 C55,117 114,125 119,130 C121,133 
		     120,137 120,140 C120,150 114,150 105,150 C92,150 79,149 66,148 C59,147 51,145 44,145 C30,145 28,156 28,167 L28,174 C28,186 28,192 37,195Z" />
  </g>
 
  <g id="bezierkurven">
		 <path d="M115,75 L150,84" stroke="#c82f04"/>	
		 <path d="M178,87 v88"  stroke="#c82f04"/>
		 <path d="M145,194 L165,189"  stroke="#c82f04"/>			 			 	
			<use xlink:href="#point" transform="translate(146,78)"/>
			<use xlink:href="#point" transform="translate(173,81)"/>		
			<use xlink:href="#point" transform="translate(173,131)"/>	
			<use xlink:href="#point" transform="translate(173,171)"/>	
			<use xlink:href="#point" transform="translate(160,184)"/>												
    </g>
 </svg>

In diesem Beispiel ist das SelfHTML-Logo als Vektorgrafik erstellt worden. Um zu verdeutlichen, wie die Pfade angelegt sind, wurden Start- und Kontrollpunkte der Kurven mit Markierungen gekennzeichnet

.

Siehe auch

Es gibt viele Anwendungsmöglichkeiten für Pfade:

CSS

Quellen

  1. w3.org: SVG Paths vom 08.07.2015
  2. w3.org: PathDataMovetoCommands
  3. w3.org: PathDataLinetoCommands (SVG2)
  4. Utility: Convert SVG path to all-relative or all-absolute commands, 6 May 2019 (lea-verou.me)
  5. WHATWG: General information about path data
  6. WHATWG: The cubic Bézier curve commands
  7. w3.org: PathDataQuadraticBezierCommands
  8. w3.org: PathDataCubicBezierCommands
  9. MDN: SVG/Tutorial/Paths#Bezier_Curves
  10. Für mathematische Details siehe "Ellipse" in der dt. Wikipedia.
  11. w3.org: PathDataEllipticalArcCommands
  12. MDN: SVG/Tutorial/Paths#Arcs
  13. W3c: 4.7. The elliptical arc curve commands

Generatoren und Visualizer