Transformacje SVG

Do tej pory wszystkie figury były wyświetlane według atrybutów x i y. Teraz pokażę jak dokonać ich transformacji np. obrotu, przeskalowania, zmiany położenia. Aby dokonać transformacji należy dodać atrybut transform do odpowiedniego elementu SVG.

Transformacja translate (transpozycja)

Jak wiemy można użyć atrybutów x i y elementu <use>, aby umieścić grupę obiektów w określonym miejscu. Spójrzmy na poniższy przykład. Położenie kwadratu jest zdefiniowane na lewy górny róg (punkt (0,0)), następnie przy użyciu <use> narysowany jest jeszcze raz ze współrzędnymi (100,100). Transformacja translate
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="kwadrat">
<rect x="0" y="0" width="40" height="40"
style="fill: orange; stroke-width: 2;"/>
</g>
<use xlink:href="#kwadrat" x="100" y="100"/>
</svg>
Teraz wykonamy to samo przekształcenie za pomocą transform. Specyficzne wartości x i y są zmienione na atrybut translate="translate(wartość x, wartość y)", gdzie translate oznacza przesunięcie. Wartość x i y są miarą aktualnego układu współrzędnych. Przesunięcie za pomocą translate daje nam taki sam efekt jak poprzednio. Przykład. Transformacja translate
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="kwadrat">
<rect x="0" y="0" width="40" height="40"
style="fill: none; stroke:black; stroke-width: 2;"/>
</g>
<use xlink:href="#kwadrat" transform="translate(100,100)"/>
</svg>
Pewnie myślicie, że jest to zrealizowane poprzez przesunięcie do odpowiedniego miejsca w układzie, lecz nie jest to prawdą (rysunek poniżej, z lewej strony). Zamiast przesuwać kwadrat polecenie translate bierzę całą siatkę i przesuwa ją w nową lokację (drugi rysunek poniżej). Transformacja translate

Transformacja scale (skalowanie)

Aby zmniejszyć lub zwiększyć nasz obiekt możemy użyć atrybutu transform="scale(wartość x, wartość y)". Jeśli wartość y nie jest podana to jest ona równa wartości x. Obydwie z tych wartości są liczbami rzeczywistymi, które informują ile razy większy lub mniejszy (w przypadku wartości ujemnych) ma być dany obiekt. Poniżej przykład transformacji skalowania. Transformacja scale
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="kwadrat">
<rect x="10" y="10" width="20" height="20"
style="fill: none; stroke: blue;"/>
</g>
<use xlink:href="#kwadrat" transform="scale(2)"/>
</svg>
Jak widać kwadrat został przeskalowany, ale jednocześnie zmienił miejsce położenia. Dlaczego tak się stało? Otórz wyjaśnienie tego faktu dobrze ilustruje poniższy rysunek. Układ nie został przesunięty, punkt (0,0) jest nadal w tym samym miejscu, ale układ użytkownika jest teraz dwa razy większy od poprzedniego. Transformacja scale Teraz użyjemy zarówno wartości x, jak i y. Przykład. Transformacja scale
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="kwadrat">
<rect x="10" y="10" width="20" height="20"
style="fill: none; stroke: blue;"/>
</g>
<use xlink:href="#kwadrat" transform="scale(3, 1.5)"/>
</svg>
Możesz dodawać transformacje nie tylko przez <use>. Można transformowac grupę obiektów:
<g id="grupa1" transform="translate(4, 7)">
<line x1="10" y1="10" x1="40" y2="40" />
<circle cx="20" cy="20" r="10" style=”fill: none; stroke: black;” />
</g>
Jak również pojedyńczy obiekt lub kształt:
<rect x="15" y="20" width="10" height="5"
transform="scale(3)"
style="fill: none; stroke: black;" />

Sekwencje transformacji

Jeśli podana jest lista przekształceń, to efekt końcowy jest taki, jak gdyby każde przekształcenie było wykonane oddzielnie w podanej kolejności. Na przykład
<g transform="translate(-10,-20) scale(3) rotate(40) translate(15,10)">
</g>
jest równoważne zapisowi
<g transform="translate(-10,-20)">
  <g transform="scale(3)">
    <g transform="rotate(40)">
      <g transform="translate(15,10)">
      </g>
    </g>
  </g>
</g>

Transformacja rotate (obrót)

Aby dobrze zrozumieć to przekształcenie należy zapamiętać, że kąty są liczone zgodnie z ruchem wskazówek zegara. Domyślnym środkiem obrotu jest punkt (0,0) (rysunek koła poniżej) Poniższy przykład ilustruje obrót o 45 stopni. Transformacja rotate Transformacja rotate
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<polyline points="100 0, 0 0, 0 100" style="stroke: black; fill: none;"/>
<!-- normal and rotated square -->
<rect x="70" y="30" width="20" height="20" style="fill: gray;"/>
<rect x="70" y="30" width="20" height="20"
transform="rotate(45)" style="fill: black;"/>
</svg>
Jak działa rotate pokazuje poniższy rysunek. Transformacja rotate Transformacja dookoła innego punktu niż (0,0) odbywa się przez polecenie rotate(kąt obrotu, punktX, punktY), gdzie punktX i punktY określają środek obrotu. Poniższy przykład ilustruje działanie tego polecenia. Obrotu dokonujemy w tym przypadku wokół środka kwadratu. Przykład Transformacja rotate
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<polyline points="100 0, 0 0, 0 100" style="stroke: black; fill: none;"/>
<!-- normal and rotated square -->
<rect x="70" y="30" width="20" height="20" style="fill: orange;"/>
<rect x="70" y="30" width="20" height="20"
transform="rotate(45,80,40)" style="fill: black; opacity: 0.4"/>
</svg>

Transformacje skewX i skewY

Transformacje te służą do przechylenia figury o okreslony kąt. Określamy je następująco: skewX(kąt) oraz skewY(kąt). Przekształcenie skewX przechyla wszystkie współrzędne x o określony kąt, współrzędne y pozostają niezmienione. Polecenie skewY zachowuję się odwrotnie. Przykład Transformacja skew
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g style="stroke: gray; stroke-dasharray: 4 4;">
<line x1="0" y1="0" x2="200" y2="0"/>
<line x1="20" y1="0" x2="20" y2="90"/>
<line x1="120" y1="0" x2="120" y2="90"/>
</g>
<g transform="translate(20, 0)">
<g transform="skewX(30)"> 
<polyline points="50 0, 0 0, 0 50" 
style="fill: none; stroke: black; stroke-width: 2;"/>
<text x="0" y="60">skewX</text> 
</g>
</g>
<g transform="translate(120, 0)">
<g transform="skewY(30)">
<polyline points="50 0, 0 0, 0 50"
style="fill: none; stroke: black; stroke-width: 2;"/>
<text x="0" y="60">skewY</text>
</g>
</g>
</svg>