PerfectVector
Autor: Irene Kim9 min czytania

Względne polecenia ścieżek SVG: śledź bieżący punkt

Odczytuj bezwzględne i względne ścieżki SVG, śledząc bieżący punkt. Sprawdź pary moveto, resetowanie przez closepath i współrzędne krzywej trzeciego stopnia na autorskim przykładzie równoważnych zapisów.

Na tej stronie

Bezwzględne polecenia ścieżek SVG, takie jak M, L i C, używają pozycji w bieżącym układzie współrzędnych użytkownika. Ich względne formy, m, l i c, używają przesunięć względem bieżącego punktu. Aby odczytać ścieżkę lub zmienić jej zapis, śledź ten punkt po każdym segmencie. Zmiana litery polecenia bez zmiany jego liczb może zmienić kształt.

Duża część nieporozumień wynika z dwóch reguł: pierwsza para początkowego m działa jak bezwzględne przesunięcie, a kolejne pary są względnymi odcinkami; z kolei Z lub z zamyka podścieżkę i przywraca bieżący punkt do jej początku. Nowe względne przesunięcie po tym zamknięciu korzysta z przywróconego punktu.

Odczytuj pozycje i przesunięcia osobno

Specyfikacja ścieżek W3C definiuje ścieżkę za pomocą jej bieżącego punktu, podścieżek i poleceń rysowania. Współrzędne są podane w jednostkach użytkownika SVG, niekoniecznie w pikselach ekranu. viewBox lub transformacja może odwzorować je na inną pozycję na ekranie.

Przy punkcie początkowym (40, 40) te dwa polecenia opisują ten sam odcinek:

L180 40
l140 0

Pierwsze określa punkt końcowy (180, 40). Drugie dodaje (140, 0) do (40, 40). Oba kończą się w punkcie (180, 40), który staje się bieżącym punktem dla następnego segmentu.

Natomiast l180 40 dodaje (180, 40) i kończy się w (220, 80). Polecenie ma poprawną składnię, ale rysuje inny odcinek.

PolecenieZnaczenie wartości określających pozycję
M x yRozpocznij podścieżkę w podanej pozycji
m dx dyRozpocznij podścieżkę względem bieżącego punktu, z uwzględnieniem opisanego niżej zachowania początkowego m
L x yNarysuj odcinek do podanej pozycji
l dx dyNarysuj odcinek do punktu wyznaczonego przez dodanie przesunięcia do współrzędnych bieżącego punktu
C / cOkreśl dwa punkty kontrolne i punkt końcowy jako pozycje lub przesunięcia względem tego samego początku
Z / zZamknij podścieżkę, łącząc ją z jej początkiem, i przywróć tam bieżący punkt

Z zapisane wielką i małą literą ma taki sam efekt: nie przyjmuje argumentów współrzędnych. Dokumentacja atrybutu d w MDN wymienia polecenia i ich poszczególne parametry.

Porównaj dwa zapisy tej samej autorskiej grafiki

Zapisz ten kompletny SVG jako absolute.svg i otwórz go w przeglądarce. Zawiera złożony znaczek w kolorze ciemnego turkusu z kwadratowym otworem oraz osobną koralową krzywą trzeciego stopnia:

<svg xmlns="http://www.w3.org/2000/svg" width="300" height="240" viewBox="0 0 300 240">
  <path class="badge" fill="#173b40" fill-rule="evenodd" d="M40 40L180 40L210 80L180 140L40 140Z M80 70L80 110L120 110L120 70Z"/>
  <path class="curve" fill="none" stroke="#f28567" stroke-width="6" d="M40 190C80 145 155 225 220 180"/>
</svg>

W pliku relative.svg zachowaj rozmiar SVG, viewBox i style, ale zastąp oba elementy ścieżek poniższymi:

<path class="badge" fill="#173b40" fill-rule="evenodd"
  d="m40 40 140 0 30 40 -30 60 -140 0z m40 30 0 40 40 0 0 -40z"/>
<path class="curve" fill="none" stroke="#f28567" stroke-width="6"
  d="m40 190c40 -45 115 35 180 -10"/>

Wyrenderowaliśmy oba autorskie pliki w przeglądarce obok celowo uszkodzonej kopii znaczka zapisanego bezwzględnie. W uszkodzonej kopii zmieniono tylko pierwsze L180 40 na l180 40; liczby pozostały bez zmian.

Rzeczywiste renderingi SVG pokazują identyczne złożone znaczki i krzywe trzeciego stopnia zapisane bezwzględnie i względnie oraz zdeformowany znaczek po zmianie wielkości litery jednego polecenia odcinka bez przeliczenia jego współrzędnych
Pierwsze dwa zapisy dają identyczny wynik. Trzeci zmienia punkt końcowy pierwszego odcinka z (180, 40) na (220, 80). Dolne panele pokazują zamknięcie podścieżki, przesunięcia krzywej trzeciego stopnia i pomiary porównywanej pary wykonane w przeglądarce.

Na naszej stronie użyliśmy natywnych metod SVG getTotalLength() i getPointAtLength(), aby porównać 301 próbek na każdej ścieżce przy odpowiadających sobie ułamkach całkowitej długości. Wyświetlone długości wynosiły 657.082 jednostek użytkownika dla każdego znaczka i 189.066 dla każdej krzywej. Maksymalna różnica między próbkowanymi punktami była wyświetlana jako 0.000000 dla obu par.

Ten pomiar potwierdza zgodność tych konkretnych ciągów znaków, których wierzchołki odcinków i punkty krzywej trzeciego stopnia są również zgodne według poniższych obliczeń. Nie jest to dowód, że dowolna zmiana zapisu lub dowolny konwerter obsługuje każde polecenie SVG. W całym porównaniu użyto tego samego obszaru widoku bez transformacji i tych samych ustawień rysowania.

Śledź pierwsze m i jego niejawne odcinki

Nasz znaczek zaczyna się od:

m40 40 140 0 30 40 -30 60 -140 0z

Tylko pierwsza para wykonuje przesunięcie. Pozostałe pary zachowują się jak niejawne względne segmenty l. Definicja moveto wyraźnie zachowuje względny charakter tych późniejszych par, mimo że początkowe m40 40 jest traktowane jako bezwzględny początek.

Śledź każdą parę po kolei:

Para lub polecenieOperacjaBieżący punkt po operacji
m40 40Początkowe przesunięcie(40, 40)
140 0Niejawny względny odcinek(180, 40)
30 40Niejawny względny odcinek(210, 80)
-30 60Niejawny względny odcinek(180, 140)
-140 0Niejawny względny odcinek(40, 140)
zZamknięcie podścieżki przez powrót do jej początku(40, 40)

Dla porównania, M zapisane wielką literą z wieloma parami zamieniłoby późniejsze pary w niejawne bezwzględne segmenty L. Nie traktowałoby każdej pary jako kolejnego przesunięcia i nie używałoby tych samych przyrostów co ten przykład z małą literą.

Każdy element ścieżki ma własną sekwencję poleceń. Nie rozpoczynaj jego początkowego względnego m od punktu końcowego niezwiązanego z nim poprzedniego elementu ścieżki.

Użyj początku zamkniętej podścieżki jako punktu odniesienia dla kolejnego przesunięcia

Otwór zaczyna się po pierwszym z:

m40 30 0 40 40 0 0 -40z

W tym momencie bieżący punkt to (40, 40), więc nowe względne przesunięcie dodaje (40, 30) i rozpoczyna otwór w (80, 70). Jego niejawne odcinki docierają następnie do (80, 110), (120, 110) i (120, 70), po czym podścieżka się zamyka.

Jeśli przez pomyłkę użyjesz punktu końcowego ostatniego odcinka zewnętrznego znaczka, czyli (40, 140), jako punktu odniesienia, rozpoczniesz nową podścieżkę w (80, 170). To wcześniejsze zamknięcie sprawia, że takie obliczenie jest błędne. Definicja closepath przywraca bieżący punkt do punktu początkowego bieżącej podścieżki.

Obie podścieżki należą do jednego elementu ścieżki. Jego fill-rule="evenodd" sprawia, że wewnętrzny kwadrat jest otworem w tym przykładzie testowym. Przy porównywaniu zmian zapisu współrzędnych zachowaj tę samą regułę wypełnienia i ustawienia rysowania, aby zmiana wypełnienia nie przesłoniła testowanej geometrii.

Odmierzaj każdy punkt kontrolny krzywej trzeciego stopnia od tego samego punktu początkowego

Osobna krzywa zaczyna się w (40, 190):

M40 190 C80 145 155 225 220 180
m40 190 c40 -45 115 35 180 -10

W tym jednym segmencie c zapisanym małą literą wszystkie trzy pary są przesunięciami względem (40, 190). Drugiego punktu kontrolnego nie odmierzasz od pierwszego, a punktu końcowego nie odmierzasz od drugiego.

PunktPara względnaPozycja bezwzględna
Pierwszy punkt kontrolny(40, -45)(80, 145)
Drugi punkt kontrolny(115, 35)(155, 225)
Punkt końcowy(180, -10)(220, 180)

Po segmencie ustaw bieżący punkt na jego punkt końcowy (220, 180). Kolejny względny segment korzystałby z tego nowego początku. Samouczek ścieżek MDN wyjaśnia punkty kontrolne krzywych trzeciego stopnia oraz formy bezwzględne i względne; poradnik łączenia krzywych Béziera osobno omawia uchwyty stycznych i skrótowe polecenie S.

Nie stosuj odejmowania współrzędnych do każdej liczby w każdym poleceniu. W łuku promienie, obrót i flagi pełnią inne funkcje; tylko para określająca punkt końcowy zmienia się między pozycją bezwzględną a względną. Zajrzyj do wyjaśnienia flag łuku, zanim zmienisz zapis danych A lub a. Ten przykład pokazuje odcinki, przesunięcia, zamknięcie i jeden zwykły segment krzywej trzeciego stopnia, a nie ogólną procedurę konwersji ścieżek.

Przesuwaj grafikę, nie myląc jej położenia ze składnią ścieżki

W przypadku tego złożonego znaczka zapisanego w całości względnie zmiana początkowego m40 40 na m60 60 przesuwa jego wierzchołki o (20, 20): późniejsze przyrosty i względne przesunięcie rozpoczynające podścieżkę podążają za zmienionym początkiem. Osobna ścieżka krzywej pozostaje bez zmian. W danych mieszanych późniejsze pozycje bezwzględne nadal pozostają przypisane do określonych współrzędnych, więc edycja pierwszego przesunięcia może zdeformować ścieżkę.

Aby przesunąć całą grafikę złożoną z dwóch ścieżek jako jedną całość, zachowaj oba ciągi d i umieść ich elementy w grupie z transform="translate(20 20)". Specyfikacja układów współrzędnych SVG wyjaśnia, jak transformacje tworzą odwzorowania współrzędnych. Transformacja grupy zmienia położenie bez zmiany oryginalnych danych ścieżek.

Sprawdź, czy przesunięta grafika nadal mieści się w obszarze widoku; przesunięcie grupy nie powiększa automatycznie jej płótna. Poradnik kolejności transformacji SVG omawia położenie przy łączeniu przesunięcia ze skalowaniem.

Sprawdź geometrię źródłową, zanim zmienisz jej zapis

PerfectVector może pomóc, gdy grafika istnieje tylko jako PNG lub JPG. Przygotuj wersję SVG do oceny, a następnie porównaj jej odtworzony kontur, otwory i kształt krzywej z obrazem źródłowym, zanim zaczniesz edytować dane ścieżek. Zapis bezwzględny lub względny nie przesądza o tym, czy odtworzona geometria nadaje się do Twojego celu.

Skorzystaj bezpośrednio z dostępnego wektorowego pliku źródłowego albo przerysuj prosty symbol, gdy łatwiej w ten sposób kontrolować rezultat. Zmiana zapisu poleceń nie pozwoli odzyskać zamierzonego kształtu, jeśli w obrazie rastrowym brakuje potrzebnych informacji. Omówienie wektoryzacji obrazów wyjaśnia ten osobny etap rekonstrukcji.

Podczas edycji SVG nadającego się do użycia zachowaj kopię oryginału, zmieniaj po jednym obsługiwanym segmencie i porównuj rzeczywisty plik w tej samej skali. Śledź zarówno początek podścieżki, jak i bieżący punkt. Zachowaj ustawienia wypełnienia i obrysu podczas porównania, a następnie przetestuj wyeksportowany plik w aplikacji, w której będzie używany.

Najczęściej zadawane pytania

Czy pierwsze m zapisane małą literą jest względne wobec innej ścieżki? Nie. Gdy m jest pierwszym poleceniem ścieżki, jego pierwsza para jest traktowana jako bezwzględny początek. Kolejne pary są niejawnymi względnymi odcinkami, a punkt końcowy innego elementu ścieżki nie stanowi punktu odniesienia dla tego początku.

Gdzie znajduje się bieżący punkt po Z lub z? Na początku podścieżki, która właśnie została zamknięta. Kolejne względne przesunięcie korzysta z tego przywróconego punktu, a nie z punktu końcowego poprzedniego odcinka.

Czy mogę przekonwertować ścieżkę, zapisując jej polecenia małymi literami? Nie. Wartości pozycji trzeba przeliczyć zgodnie ze znaczeniem każdego polecenia. W tym przykładzie L180 40 zmienia się w l140 0 przy bieżącym punkcie (40, 40), natomiast l180 40 rysuje inny odcinek.

Źródła

  1. W3C — SVG 2 Paths — Definiuje bieżące punkty, początkowe moveto, niejawne odcinki, zamknięcie i parametry krzywych trzeciego stopnia.
  2. MDN — Paths tutorial — Ilustruje bezwzględne i względne polecenia odcinków i krzywych.
  3. MDN — d attribute — Wymienia role parametrów poleceń, w tym łuków i closepath.
  4. W3C — SVG 2 Coordinate Systems — Wyjaśnia odwzorowania współrzędnych użytkownika i pozycjonowanie grafiki za pomocą transformacji.

Masz tylko grafikę rastrową? Przygotuj ścieżki SVG z PerfectVector, sprawdź odtworzony kontur i otwory, a następnie edytuj tylko polecenia, które rozumiesz, i porównaj wynikowy SVG z oryginałem.

Więcej z bloga

Zacznij od czystszego SVG,
który łatwiej edytować