SVG/Tutorials/Gruppierungen

Aus SELFHTML-Wiki
< SVG‎ | Tutorials
Wechseln zu: Navigation, Suche

Im Allgemeinen bestehen SVG-Grafiken aus Objekten, die sich aus einer oder mehreren Grundformen, Pfaden oder Text zusammensetzen. Diese Objekte kannst du gruppieren, um sie zu gestalten, zu verschieben oder als Vorlage mehrfach aufzurufen.

Gruppierungen

g

Mit dem g-Element (group) kannst du mehrere Objekte zu einer Gruppe zusammenfassen. Dabei hat das Element ähnlich wie das div in der HTML-Welt keine weitere Bedeutung. Die Stilangaben aller Kindelemente kannst du dann zentral festlegen, sie werden an die Kindelemente vererbt.


Folgende Angaben sind möglich:

SVG-Objekt Auto ansehen …
#auto {
  fill: #c32e04;
  stroke: black;  
  stroke-width: 0.5;
}

#auto circle {
  stroke-width: 4;
}
<g id="auto">
	<path id="body" d="M30,50 v-15 h15 l15,-15 h30 l15,15 h15 v15z" />
	<circle id="wheel1" cx="50" cy="50" r="8" />
	<circle id="wheel2" cx="100" cy="50" r="8" />
</g>

Das Beispiel demonstriert die Funktionsweise des g-Elements. Es werden drei Formen (ein Pfad und zwei Kreise) gruppiert. Die Stilangaben für Füllung, Randfarbe und -dicke werden zentral im g-Element festgelegt und an die Kindelemente vererbt.

Für die Kreise wird die stroke-width mit #auto circle überschrieben


Manko: fehlende X- und Y-Attribute

Leider kann man das g-Element nicht verschieben, da es keine x- und y-Attribute akzeptiert. Einen Ausweg bietet die Verschachtelung in einem SVG-Element, das beliebig positioniert werden kann.

Verschiebung eines g-Elements mit weiterem svg-Element ansehen …
<g id="auto">
	<path id="body" d="M30,50 v-15 h15 l15,-15 h30 l15,15 h15 v15z" />
	<circle id="wheel1" cx="50" cy="50" r="8" />
	<circle id="wheel2" cx="100" cy="50" r="8" />
</g>	

<svg x="200" y="100">
	<g id="auto2">
		<path id="body" d="M30,50 v-15 h15 l15,-15 h30 l15,15 h15 v15z" />
		<circle id="wheel1" cx="50" cy="50" r="8" />
		<circle id="wheel2" cx="100" cy="50" r="8" />
	</g>	
</svg>

Das zweite g-Element wird innerhalb eines svg-Elements verschachtelt und erbt dessen Position.


Transformationen

Eine weitere Möglichkeit eine Gruppierung zu verschieben, bietet das transform-Attribut mit der translate-Funktion.

  • transform="translate(x,y)"

Darüber hinaus kann man auch die anderen Funktionen wie Rotieren, Skalieren oder Verzerren verwenden und mit SMIL, CSS oder JavaScript animieren.


Gruppierung mit transform verschieben ansehen …
.auto:nth-of-type(2) {
  fill: #dfac20;
  animation: run 3s linear infinite;
}

@keyframes run {
  0% {transform: translate(-50px,0px);}
  100% {transform: translate(400px,0px);}
}

Es werden zwei Autos mit denselben Geometrie-Abmessungen gezeichnet. Damit sie nicht übereinanderliegen und sich verdecken, wird das zweite Auto mit .auto:nth-of-type(2) selektiert und mit transform in einer CSS-Animation verschoben.

Dieses Beispiel dupliziert das Auto, indem das SVG-Markup einfach erneut notiert wird. Du kannst eine mit dem g-Element zusammengefasste Gruppe von Objekten aber mehrfach verwenden, wenn du sie mit dem use-Element referenzierst und aufrufst.

symbol

Mit dem symbol-Element kannst du Objekte wie z. B. Icons gruppieren und mit einer ID eindeutig identifizieren. Diese Objekte werden wie Objekte im Definitionsabschnitt nicht gerendert, können mithilfe des use-Elements aber beliebig oft aufgerufen werden.


Empfehlung: Verwende das symbol-Element anstelle von g, wenn du Objektgruppen wiederverwenden willst.

Dies bringt viele Vorteile mit sich:

  • Anders als das g-Element kann man beim symbol-Element folgende Attribute setzen:
So können beliebige Grafiken passend skaliert eingebunden werden.
  • Der Code wird übersichtlicher
  • die Wiederverwendbarkeit führt bei häufiger Verwendung zu geringeren Datei-Größen
  • durch die Verwendung von Metadaten wie title und desc wird der Code zugänglicher.
Gruppierung mit symbol ansehen …
<symbol id="wheel" x="-10" y="-10" height="20" width="20" viewBox="-10 -10 20 20">
	<desc>Autoreifen mit Ventil, damit eine Rotation später sichtbar wird</desc>
	<circle cx="0" cy="0" r="8" />
	<path d="m0,6 v2" />
</symbol>

<use href="#wheel" x="100" y="100" height="20" width="20" />
<use href="#wheel" x="150" y="100" height="20" width="20" />	
	
<use href="#wheel" x="-150" y="100" height="20" width="20" />
<use href="#wheel" x="-100" y="100" height="20" width="20" />

In diesem Beispiel wird ein symbol mit der id wheel angelegt. Es enthält eine Beschreibung mit desc, den schon bekannten Kreis mit der Randlinie als Reifen und der Füllung als Radkappe und zusätzlich einen Pfad, der eine Ventilkappe darstellen soll.

Das symbol-Element enthält ein viewBox-Attribut, das um den Urspung zentriert ist (viewBox="-10 -10 20 20"). Zusätzlich erhält es die gleichen Werte als Attribute(x="-10" y="-10" height="20" width="20"). Dadurch erfolgt keine Skalierung (bzw. Faktor 1) und das Symbol wird innerhalb der Viewbox richtig positioniert. Ohne Positionierung sind nur positive Koordinaten möglich.

Das symbol-Element selbst wird nicht dargestellt, jedoch viermal über seine id referenziert und mit einem use-Element aufgerufen.

Beachte: Wenn du für symbol eine viewBox angibst, wird das aufgerufene use-Element auf die volle Größe des svg skaliert. In den Chromium-Browsern und im Firefox ist es auch ohne Breiten- und Höhenangaben 20 x 20 Einheiten groß. Damit es im Safari in der passenden Größe dargestellt wird, ist eine Angabe von width und height nötig.
Beachte: Innerhalb von symbol sind nur Grundformen, Pfade oder Text, aber keine use-Elemente erlaubt.

Aufrufen von Gruppierungen

use

Mit dem use Element kannst du ein vorher festgelegtes Objekt wie eine einzelne Grundform oder einen Text, eine Gruppierung mit g oder symbol über die ID beliebig oft aufrufen. So sparst du Speicherplatz und hältst deine SVG-Grafiken übersichtlich.


Folgende Angaben sind möglich:

  • x: neue X-Position des Objekts
  • y: neue Y-Position des Objekts
  • width: Breite des Anzeigeraums
  • height: Höhe des Anzeigeraums
  • alle Präsentationsattribute
Aufrufen mit use ansehen …
<symbol id="wheel" height="20" width="20" viewBox="-10 -10 20 20">
	<desc>Autoreifen mit Ventil, damit eine Rotation später sichtbar wird</desc>
	<circle cx="0" cy="0" r="8" />
	<path d="m0,6 v2" />
</symbol>
	<use href="#wheel" x="100" y="100" height="20" width="20" />
	<use href="#wheel" x="150" y="100" height="20" width="20" />
	<use href="#wheel" x="-150" y="100" height="20" width="20" />
	<use href="#wheel" x="-100" y="100" height="20" width="20" />
Beachte: Die x- und y-Koordinaten des use-Elements werden zu den schon vorhandenen des aufgerufenen Elements dazu addiert, so als hätte man transform="translate(x y)" angegeben (falls weitere Transformationen angegeben sind, wird die hier genannte zuerst ausgeführt, also so als ob sie am Ende des Attributwertes stände).

Styling des use-Elements

Styling des use-Elements ansehen …
<defs>
	<symbol id="wheel" x="-10" y="-10" height="20" width="20" viewBox="-10 -10 20 20" >
		<desc>Autoreifen mit Ventil, damit eine Rotation später sichtbar wird</desc>
		<circle cx="0" cy="0" r="8" />
		<path id="valve" d="m0,-6 v2" />
	</symbol>

	<g id="auto">
		<path id="body" d="M 0,30 v-15 h15 l15,-15 h30 l15,15 h15 v15z" />
		<use href="#wheel" x="20" y="30" height="20" width="20"/>
		<use href="#wheel" x="70" y="30" height="20" width="20"  />
	</g>	
</defs>

	<use href="#auto" x="50" y="50" style="fill:#c32e04"/>
	<use href="#auto" x="100" y="25"  style="fill:#5a9900; animation-duration: 4s;"/>
	<use href="#auto" class="truck" x="250" y="5" />	
	<use href="#auto" x="200" y="5" />

Neben dem schon bekannten Reifen #wheel wird nun eine Gruppierung #auto angelegt und mehrfach mit use aufgerufen.

Die einzelnen use-Elemente werden durch Klassen oder inline-Styles entsprechend gefärbt, transformiert und animiert.

Wenn du das <use>-Element über eine Klasse oder eine strukturelle Pseudoklasse wie nth-of-type selektierst, kannst du, falls diese Eigenschaften vorher nicht deklariert wurden, Randfarbe, -stärke und Füllung des <use>-Elements formatieren. Dies gilt jedoch nicht für die in der Vorlage verwendeten Kind-Elemente.

Beachte: Ich hatte jetzt 2x mal unabhängig voneinander den Fehler gemacht, das use-Element über die id des symbol-Elements zu stylen! Das funktioniert natürlich nicht; das use-Element benötigt dann eine eigene, unverwechselbare id:
<use href="#auto" id="einmalig" x="50" y="50" style="fill:#c32e04"/>

use im Shadow-DOM

MIt use referenzierte Elemente können zwar aus beliebig vielen SVG-Elementen bestehen, werden auf dem Bildschirm (und im DOM der Seite) als ein Element dargestellt. Bei einem Blick in den Seiteninspektor sieht man, dass die einzelnen Teil-Elemente im #shadow-root-Knoten des use-Elements gekapselt sind. Ein direkter Zugriff auf diese Kindelemente ist nicht möglich.

Styling mit custom properties

Einen Ausweg bietet die Verwendung von Custom properties. Diese werden in die von <use> erstellte Kopie hineinvererbt und können deshalb von den Kindelemente der symbol-Vorlage benutzt werden, um beispielsweise eine Farbe zu setzen.

Syntax für custom properties
svg {
  --akzentfarbe: #c32e04;
}

path {
  fill: var(--akzentfarbe);
}

Im Beispiel wird eine Farbe festgelegt. Der Wert einer benutzerdefinierten Eigenschaft wird mit einem frei gewählten Namen festgelegt. Dieser beginnt mit zwei Minuszeichen.

Anschließend kann diese Variable im gesamtem Dokument mit der Variablenfunktion var() wieder aufgerufen werden.

Styling des use-Elements mit custom properties ansehen …
<defs>
	<symbol id="wheel" x="-10" y="-10" height="20" width="20" viewBox="-10 -10 20 20" >
		<desc>Autoreifen mit Ventil, damit eine Rotation später sichtbar wird</desc>
		<circle style="fill: var(--accentcolor2);" cx="0" cy="0" r="8" />
		<path id="valve" d="m0,-6 v2" />
	</symbol>

	<g id="auto">
		<path id="body" style="fill: var(--bodycolor);" d="M 0,30 v-15 h15 l15,-15 h30 l15,15 h15 v15z" />
		<path id="windows" style="fill: var(--accentcolor1); stroke-width:0;" d="M 19,15 h24 v-13 h-11 z m 27,0 h24 l-13,-13 h-11z"  />
		<use href="#wheel" x="20" y="30" height="20" width="20"/>
		<use href="#wheel" x="70" y="30" height="20" width="20"  />
	</g>	
</defs>

<use href="#auto" x="50" y="50" style="--bodycolor: #c32e04; --accentcolor1: #fff; --accentcolor2: white";/>
<use href="#auto" x="100" y="25"  style="--bodycolor: #5a9900; --accentcolor1: #ccc; --accentcolor2: #5a9900; animation: run 4s linear infinite;"/>

Sowohl das symbol #wheel,als auch die Gruppierung #auto enthalten style-Attribute, in denen die fill-Eigenschaft anhand von Custom Propertys festgelegt wird.

Beim Aufruf der Vorlage mit use werden für die ersten zwei Autos inline-styles verwendet, die diesen Propertys Farbwerte zuweisen.

Das hellblaue Auto wird über die Klasse truckweiterhin mit einer „normalen“ Farbangabe (fill: #e6f2f7; ) formatiert; das gelbe Auto erhält seine Formatierung über den nth-of-type-Selektor, die Custom Properties werden im zugehörigen CSS gesetzt.

Anwendungsbeispiele

Ellipsen

ein Bündel von Ellipsen - 1 ansehen …
<g id="g1">
	<ellipse id="ellipse1" cx="100" cy="100" rx="75" ry="40"/>
	<use href="#ellipse1" transform="rotate(60 100 100)"/>
	<use href="#ellipse1" transform="rotate(120 100 100)"/>
</g>

<use href="#g1" transform="rotate(20 100 100)" style="--stroke:gold" />
<use href="#g1" transform="rotate(40 100 100)" style="--stroke:#c82f04" />
Das zugehörige CSS:
g {
	fill: none;
	stroke: var(--stroke,  steelBlue));
	stroke-width: 1;
}

Innnerhalb eines g-Elements wird eine Ellipse einmal definiert, dann mit use 2x wieder aufgerufen und mittels Transform um 60° und 120° gedreht. Das Ergebnis sind 3 Ellipsen, deren große Achsen jeweils im 60°-Winkel zueinander stehen. Da für diese Darstellung das Custom Property --stroke nicht gesetzt ist, verwendet die var()-Funktion den angegebenen Defaultwert steelBlue, diese Ellipsen sind also blau.

Diese Ellipsenschar wird nun weitere zweimal aufgerufen und dabei um 20° und 40° gedreht, so dass die beiden Kopien sich gleichmäßig in die vorhandene Schar einfügen. Gleichzeitig wird mit dem style-Attribut das Custom Property --stroke auf einen Farbwert gesetzt. Das Custom Property wird in das vom <use>-Element erzeugte Schatten-DOM hineinvererbt und verändert so die Farbe, die für die Kopie verwendet wird.

Achtung!

Um dieses Beispiel zu untersuchen, öffnen Sie bitte …
  1. das Beispiel mit einem Klick auf Vorschau in einem neuen Tab!
  2. den Seiteninspektor mit F12!
ein Bündel von Ellipsen - 2 ansehen …
<g id="firstone" stroke="gold">
<animateTransform attributeName="transform" id="AT" additive="sum" type="translate" dur="7s" values="50 0;0 0;50 0" repeatCount="indefinite"/>
	<g id="g3" fill="none" stroke-width="2">
		<animateTransform attributeName="transform" type="rotate" dur="4s" from="180 100 100" to="0 100 100" repeatCount="indefinite"/>
		<g id="g2">
			<ellipse id="g1" cx="100" cy="100" rx="75" ry="40">
				<animate attributeName="ry" dur="3s" values="10; 60; 10" repeatCount="indefinite"/>
			</ellipse>
			<use href="#g1" transform="rotate(30 100,100)"/>
			<use href="#g1" transform="rotate(60 100,100)"/>
		</g>
		<use href="#g2" transform="rotate(90 100 100)"/>
	</g>
</g>

<use href="#g3" transform="translate(50 0)" stroke="steelBlue">

<use href="#AT"/>
	<animateTransform attributeName="transform" additive="sum" type="translate" dur="7s" values="0 0;50 0;0 0" repeatCount="indefinite"/>
</use>

<use href="#g3" transform="translate(50 50)" stroke="green">
	<animateTransform attributeName="transform" additive="sum" type="translate" dur="7s" values="0 -50;50 0;0 -50" repeatCount="indefinite"/>
</use>

<use href="#g3" transform="translate(0 50)" stroke="#c82f04">
	<animateTransform attributeName="transform" additive="sum" type="translate" dur="7s" values="50 -50;0 0;50 -50" repeatCount="indefinite"/>
</use>

Eine Ellipse wird einmal definiert, dann mit use wieder aufgerufen und mittels animateTransform immer wieder so gedreht, dass stets neue Muster und Formen erscheinen.

Osterwiese

Osterwiese ansehen …
<defs>
  <symbol id="ei">
    <path d="M1,90 a 60,60 0 0 0 120,0 a 60,90 0 1 0 -120,0" stroke="black" stroke-width="1"/>
  </symbol>

  <symbol id="tulpe" stroke="black" stroke-width="1">
    <path d="M40,60 c0,0 -5,-20 12,-30 c10,10 15,20 15,75 h-30" />
    <path d="M55,80 c5,-20 20,-50 33,-50 c30,140 -93,110 -73,8 c20,0 55,55 47,86 " />
  </symbol>
  <symbol id="stengel" stroke="black" stroke-width="1" fill="url(#gruen)">
    <path d="M55,125 c10,10 16,60 15,80 h8 c0,-10 0,-60 -12,-80" />
    <path d="M50,265 c0,-30 6,-60 60,-110 c-40,50 6,90 -60,110 c-40,-50 26,-90 -45,-150 c70,30 50,100 
             55,100" />
  </symbol>
	  
  <radialGradient id="rot" cx="88%" cy="45%">
    <stop offset="0%" stop-color="silver" />
    <stop offset="100%" stop-color="#c32e04" />
  </radialGradient>
  <radialGradient id="gruen" cx="88%" cy="45%">
    <stop offset="0%" stop-color="silver" />
    <stop offset="100%" stop-color="#5a9900" />
  </radialGradient>
  <radialGradient id="gelb" cx="88%" cy="45%">
    <stop offset="0%" stop-color="silver" />
    <stop offset="100%" stop-color="#dfac20" />
  </radialGradient>
  <radialGradient id="blau" cx="88%" cy="45%">
    <stop offset="0%" stop-color="silver" />
    <stop offset="100%" stop-color="#3983ab" />
  </radialGradient>
  <linearGradient id="hintergrund" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" stop-color="white" />
    <stop offset="10%" stop-color="#e6f2f7" />
    <stop offset="50%" stop-color="#5c82d9" />
    <stop offset="50%" stop-color="#8db243 " />
    <stop offset="100%" stop-color="#ebf5d7" />
  </linearGradient>	   
</defs>
	
<rect x="0" y="0" width="880" height="500" fill="url(#hintergrund)" />

<g fill="url(#gelb)" transform="translate(0,0)">
   <use href="#tulpe" />
   <use href="#stengel" />
</g>

<g fill="url(#rot)" transform="translate(200,0) scale(-1,1)" >
  <use href="#tulpe" />
  <use href="#stengel" />
</g>
	 
<g fill="url(#blau)" transform="translate(620,30) rotate(-20)">
  <use href="#tulpe" />
  <use href="#stengel" />
</g>
<g fill="url(#gelb)" transform="translate(850,10) scale(-1,1)" >
  <use href="#tulpe" />
  <use href="#stengel" />
</g>
   
<use fill="url(#rot)" href="#ei" transform="translate(70,220) rotate(-10,50,30) scale(.5,.5)" />
<use fill="url(#gelb)" href="#ei" transform="translate(30,250) scale(.5,.5)" />
<use fill="url(#blau)" href="#ei" transform="translate(100,250) rotate(30,50,50) scale(.5,.5)" />
	
<g transform="translate(600,360) scale(.5,.5)">
  <use fill="url(#gelb)" href="#ei" transform="translate(0,0)" />
  <use fill="url(#blau)" href="#ei" transform="translate(100,50) rotate(30,50,50)" />
  <use fill="url(#rot)" href="#ei" transform="translate(-100,50) rotate(-30,50,30)" />	
  <use fill="url(#gruen)" href="#ei" transform="translate(0,100) rotate(-10)" />
</g>

Im Definitionsabschnitt werden mehrere symbol-Elemente definiert:

  • ein ovales Ei
  • eine Tulpenblüte ohne fill-Attribut
  • Stengel und Blätter mit grüner Füllung

Anschließend werden diese Objekte mit use aufgerufen. Tulpe und Stengel sind in einem g-Element, das durch das transform-Attribut an die richtige Stelle verschoben wurde. Die mit use aufgerufenen Objekte erhalten eine jeweils andere Füllfarbe und werden bei Bedarf noch einmal transformiert.

Diese Osterwiese wurde 2015 als Ostergruß erstellt und dient dem Osterspiel 2024 als Hintergrund.


Eine Burg

Auf einigen Seiten ist eine Burg eingebunden. Hier kannst du sie noch einmal als Beispiel sehen:

 <defs>
    <style type="text/css">
      <![CDATA[
#turm {
  stroke: black;
  stroke-width: 1;
  fill:url(#mauerwerk);
}

#mauerwerk,#holz,#banner {
  stroke: black;
  stroke-width: 1;
}

#mauer {
  fill:url(#mauerwerk);
}]]></style> 

    <pattern id="mauerwerk" x="0" y="0" width="48" height="19" patternUnits="userSpaceOnUse">
      <rect width="48" height="20" fill="#FFF8DC" stroke-width="0"/>
      <path d="M0,1 h48"/>
      <path d="M0,10 h48"/>
      <path d="M12,1 v9"/>
      <path d="M36,1 v9"/>
      <path d="M1,10 v9"/>
      <path d="M25,10 v9"/>
    </pattern>

    <pattern id="holz" x="0" y="0" width="5" height="17" patternUnits="userSpaceOnUse">
      <rect width="5" height="20" fill="#9c4822" stroke-width="0"/>
      <path d="M0,0 v20"/>
    </pattern>
	
    <linearGradient id="hintergrund" y1="0%" x2="0%" y2="100%">
      <stop offset="0%" stop-color="white" />
      <stop offset="10%" stop-color="#e6f2f7" />
      <stop offset="100%" stop-color="#5c82d9" />
    </linearGradient>	 
	
    <radialGradient id="gelb" cx="50%" cy="50%">
      <stop offset="0%" stop-color="yellow" />
      <stop offset="100%" stop-color="#dfac20" />
    </radialGradient>
	
	
    <symbol id="turm">
      <desc>Turm der Burg</desc>
      <path d="M1,1 h8 v9 h8 v-9 h8 v9h8 v-9 h8 v15 l-5,5 v50 h-30 v-50 l-5,-5 v-15 z" />
      <rect x="20" y="29" width="5" height="10" fill="black"/>
    </symbol>
    <symbol id="mauer">
      <desc>Definition fuer eine Mauer gefuellt mit Muster "Mauerwerk"</desc>
      <rect id="mauer" x="0" y="0" width="160" height="90" />
    </symbol>
    <symbol id="tor">
      <desc>Definition für das Tor</desc>
      <path d="M0,50 a25,25 0 0,1 50,0 v40 h-50 z"/>
    </symbol>
    <symbol id="banner">
      <desc>Definition für das Banner</desc>
      <path d="M10,7 v28"/>
      <path d="M10,10 c20,-5 -5,5 15,5 c15,0 -5,5 15,5 h5 l-3,3 l3,3 c10,3 -15,-5 -20,-5 c5,-3 
               -10,0 -15,-5 z"/>
    </symbol>
  </defs>

  <g> 
    <rect width="160" height="200" fill="url(#hintergrund)"/>
    <use href="#turm" x="10" y="56" />
	<use href="#banner" x="55" y="6" fill="#c32e04"/>
	<use href="#turm" x="110" y="56" />
	<use href="#banner" x="5" y="22" fill="#3983ab"/>
	<use href="#turm" x="60" y="40" />
	<use href="#banner" x="105" y="22" fill="purple"/>
	<use href="#mauer" x="0" y="110" />
	<use href="#tor" x="55" y="120" fill="url(#holz)"/>
	<circle r="15" fill="url(#gelb)"/>
  </g>

Die Burg besteht aus nur wenigen symbol-Elementen wie z. B. der Turm oder das Banner, die dann mit use mehrfach aufgerufen werden.

Das Mauerwerk und die Holz-Optik des Tores wurde mit Hilfe eines pattern-Musters gestaltet, das dann im fill-Attribut aufgerufen wird.

Der Himmel und die Sonne wurden mit Farbverläufen gefüllt.

Tangram

Beispiel ansehen …
<svg>
 <defs>
    <title>Vorlagen für Tangram-Figuren</title>
    <symbol id="dreieck_gr">
      <desc>das große Dreieck</desc>
      <path d="m0,0 132,132 132-132z"/>
    </symbol>
	<symbol id="dreieck_m">
      <desc>das mittlere Dreieck</desc>
      <path d="m0,0 h132 v132 z"/>
    </symbol>
	<symbol id="dreieck_kl">
      <desc>das kleine Dreieck</desc>
      <path d="m0,66 l66,66v-132z"/>
    </symbol>
	<symbol id="quad">
      <desc>das quadratische Rechteck</desc>
      <path d="m0,0 v94 h94 v-94z"/>
    </symbol>
	<symbol id="para">
      <desc>das Paralellogramm</desc>
      <path d="m66,0 l-67,67 v132 l67-67 z"/>
    </symbol>
	
    <symbol id="viereck">
      <text x="10" y="280">Quadrat</text>
      <use href="#dreieck_gr" class="eins"/>
      <use href="#dreieck_gr" class="zwei" transform="scale(-1 1) rotate(90)"/>
      <use href="#dreieck_m" class="drei" transform="translate(264,132) rotate(90)"/>
      <use href="#dreieck_kl" class="vier" x="132" y="66"/>  
      <use href="#quad" class="sechs" transform="translate(132,132) rotate(45)"/>
      <use href="#para" class="sieben" x="198" y="0"/>      
      <use href="#dreieck_kl" class="fuenf" transform="translate(132,197) rotate(90)"/>
    </symbol> 
	 
    <symbol id="schiff">  
      <text x="40" y="250">Schiff</text>
      <use href="#dreieck_gr" class="eins" transform="translate(140,0) rotate(90)"/>
      <use href="#dreieck_gr" class="zwei" transform="translate(290,0)  rotate(90)"/>
      <use href="#dreieck_m" class="drei" transform="translate(400,80) scale(-1 1) rotate(45)"/>
      <use href="#dreieck_kl" class="vier" transform="translate(281,218) rotate(45)"/> 
      <use href="#para" class="sieben" transform="translate(374,218) rotate(45) "/> 
      <use href="#dreieck_kl" class="fuenf" transform="translate(187,311) rotate(135)"/>
      <use href="#quad" class="sechs" transform="translate(140,264)"/>
    </symbol>
  </defs>

   <use href="#viereck" x="10" y="10"/>  
   <use href="#schiff" x="400" y="10"/>  

</svg>

Tangram ist ein chinesisches Legespiel, in dem ein Quadrat in 7 geometrische Formen zerschnitten wird, die dann beliebig zu neuen Bildern gedreht, gespiegelt und verschoben werden.

Da es beim Rotieren, Spiegeln und Verschieben zu Rundungsfehlern kommen kann, wurde den Figuren ein 1 Einheiten breiter weißer Rand gegeben, der das Gesamtbild besonders im ersten Beispiel gleichmäßiger aussehen lässt.

Weblinks


SVG-use, Shadow DOM und custom properties

Referenz