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).
<?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.

<?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 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.
<?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.


<?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.

<?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.


<?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
<?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>