Lekcja 8. Transformacje

wrz 3, 2026 | Kurs SVG

translate, rotate, scale — i kolejność, która zmienia wszystko

Do tej pory każdy kształt rysowaliśmy tam, gdzie miał być. Transformacje pozwalają zrobić inaczej: narysować kształt w wygodnym miejscu, a potem przesunąć go, obrócić albo przeskalować — bez ruszania choćby jednej współrzędnej w środku.

Służy do tego jeden atrybut:

html

<g transform="translate(70 90) rotate(45)">

Można go postawić na pojedynczym kształcie albo — częściej i sensowniej — na grupie <g>, żeby objął wszystko w środku.

Cztery funkcje

translate(x y) przesuwa. Druga liczba jest opcjonalna; translate(40) przesuwa tylko w poziomie.

rotate(kąt) obraca. Kąt w stopniach, dodatni zgodnie ze wskazówkami zegara — bo oś Y rośnie w dół, o czym była lekcja pierwsza.

scale(x y) skaluje. Jedna liczba skaluje proporcjonalnie. Wartości ujemne odbijają lustrzanie: scale(-1 1) to odbicie w poziomie.

skewX(kąt) i skewY(kąt) pochylają. Rzadko potrzebne, ale to one dają efekt kursywy albo rzutu izometrycznego.

Środek, którego nie ma

Największa niespodzianka jest przy obrocie. Domyślnie wszystkie transformacje odnoszą się do punktu 0,0 — czyli lewego górnego rogu układu współrzędnych, a nie do środka figury.

Niebieska kropka pokazuje realną oś obrotu. Przesuń ją na środek kwadratu i obrót zacznie wyglądać tak, jak intuicyjnie oczekujesz. Zostaw w rogu — kwadrat zatoczy koło wokół punktu, którego nawet nie widać na figurze.

rotate przyjmuje na szczęście dwa dodatkowe argumenty:

html

rotate(45 100 100)

Kąt, a po nim współrzędne punktu, wokół którego ma się kręcić. To najprostszy sposób na obrót wokół środka i w praktyce używa się go częściej niż wersji z jednym argumentem.

scale takiej wygody nie ma. Skaluje zawsze względem 0,0, więc żeby powiększyć figurę „w miejscu", trzeba ją najpierw przesunąć do zera, przeskalować i odsunąć z powrotem. Albo — prościej — rysować kształt wokół punktu 0,0 od początku i dopiero potem przesuwać go na miejsce. Tak właśnie zbudowane są oba widgety w tej lekcji.

Kolejność ma znaczenie

Teraz rzecz najważniejsza, na której ludzie potykają się latami.

Funkcje w atrybucie transform wykonują się po kolei, a każda kolejna działa w układzie współrzędnych ustawionym przez poprzednią. To nie jest lista niezależnych poleceń. To ciąg zagnieżdżonych układów.

Po lewej translate a potem rotate: kwadrat odjeżdża w bok i kręci się wokół własnego środka. Po prawej rotate a potem translate: obrót przekręca cały układ współrzędnych, więc kolejne przesunięcie idzie już wzdłuż obróconej osi — i kwadrat krąży po orbicie. Te same dwie liczby, dwa zupełnie inne zachowania.

Jeśli szukasz reguły do zapamiętania: czytaj od lewej jako „ustaw się", a nie jako „przesuń obiekt". Pierwsza funkcja ustawia nowy układ, druga działa już w nim. Dlatego translate na początku to zwykle „gdzie to jest", a wszystko po nim to „co się z tym dzieje".

Skalowanie skaluje wszystko

Ostatnia pułapka i pewnie ta, która najczęściej psuje prawdziwe projekty.

scale() nie powiększa tylko geometrii. Powiększa też grubość obrysu, wzór kreskowania, rozmiar tekstu — wszystko.Ikona konturowa przeskalowana dwukrotnie ma obrys dwa razy grubszy, więc przestaje pasować do reszty zestawu.

Ten sam kwadrat i ta sama skala. Po lewej obrys puchnie razem z figurą, po prawej trzyma stałą grubość dzięki vector-effect="non-scaling-stroke".

vector-effect to właściwość stworzona dokładnie do tego problemu i warto o niej pamiętać przy mapach, wykresach i wszystkim, co można przybliżać — linia siatki ma zostać cienka niezależnie od zoomu.

Transformacje w CSS

Wszystkie te funkcje można też zapisać w CSS zamiast w atrybucie:

css

.ikona { transform: rotate(45deg); transform-origin: center; }

To ma dwie zalety: transform-origin: center załatwia problem osi obrotu bez liczenia współrzędnych, a transformacje w CSS można animować i wyzwalać na :hover.

Ma też dwie pułapki. Po pierwsze, w CSS kąt wymaga jednostki — rotate(45deg), nie rotate(45). Po drugie, wartości translatew CSS są interpretowane jako piksele, a w atrybucie jako jednostki użytkownika. Przy viewBox innym niż rozmiar wyświetlania to nie jest to samo.

Jest jeszcze matrix(a b c d e f), która zapisuje dowolną kombinację powyższych w sześciu liczbach. Nie pisze się jej ręcznie — pojawia się w plikach z programów graficznych i wystarczy wiedzieć, że to skrót, a nie coś nowego.

Podsumowanie

  • transform przyjmuje listę funkcji; najczęściej stawia się go na grupie <g>.
  • Domyślnym punktem odniesienia jest 0,0, a nie środek figury.
  • rotate może przyjąć oś obrotu jako dwa dodatkowe argumenty; scale nie.
  • Funkcje wykonują się po kolei, a każda działa w układzie ustawionym przez poprzednią — translate rotate to nie to samo co rotate translate.
  • scale powiększa również grubość obrysu; ratunkiem jest vector-effect="non-scaling-stroke".
  • W CSS te same funkcje wymagają jednostek i inaczej traktują translate, ale dają transform-origin i animacje.

W następnej lekcji kolory przestają być pojedynczą wartością — wchodzą gradienty i wzory, czyli wypełnienia, które są osobnymi obiektami.


Do wypróbowania: w presecie transform · kolejność ustaw przesunięcie na 0. Oba kwadraty zaczną zachowywać się identycznie — bo bez przesunięcia nie ma różnicy między obrotem wokół siebie a orbitą o promieniu zero. To najprostszy dowód, że kolejność ma znaczenie tylko wtedy, gdy obie operacje faktycznie coś robią.