Jak przerwać linię i dlaczego to jest ważniejsze, niż się wydaje
Przerywana linia wygląda na drobiazg dekoracyjny. W SVG jest czymś więcej: to jedyny mechanizm, który operuje na długości ścieżki, a nie na jej kształcie. Dzięki temu na nim właśnie stoi efekt rysującej się linii, wskaźniki postępu w pierścieniach i połowa animacji, które ludzie uznają za magię.
Zaczynamy jednak od podstaw, bo one same w sobie mają dwie niespodzianki.
Kreska i przerwa
html
stroke-dasharray="12 8"
Pierwsza liczba to długość kreski, druga to długość przerwy. Wzór powtarza się wzdłuż całej ścieżki, aż do jej końca.
Wartości podaje się w jednostkach użytkownika mierzonych wzdłuż ścieżki — nie w pikselach ekranu i nie w procentach. Przy viewBox="0 0 100 100" kreska o długości 12 zajmuje 12% szerokości płótna, niezależnie od tego, jak duży jest obrazek na ekranie.
Trzeci suwak to
stroke-dashoffset— przesunięcie całego wzoru wzdłuż linii. Wartości dodatnie cofają wzór, ujemne przesuwają do przodu. Sam w sobie nie robi nic ciekawego. Zanimowany robi wszystko.
Więcej niż dwie liczby
Wzór nie musi być dwuelementowy. Wartości czyta się po prostu na przemian: kreska, przerwa, kreska, przerwa, i tak w kółko.
html
stroke-dasharray="14 6 2 6"
To daje klasyczny wzór kreska-kropka: długa kreska, przerwa, krótka kreska, przerwa — i od nowa.
Cztery suwaki, cztery elementy wzoru. Ustaw drugą kreskę na 0, a wzór zamieni się w zwykłą linię przerywaną z podwójną przerwą.
I tu pierwsza niespodzianka. Gdy liczb jest nieparzyście dużo, lista jest powtarzana dwukrotnie. Zapis 5 10 15przeglądarka rozumie jako 5 10 15 5 10 15.
Efekt jest taki, że role się odwracają w połowie cyklu: to, co w pierwszym przebiegu było kreską, w drugim staje się przerwą. Dlatego wzór z nieparzystą liczbą wartości wygląda inaczej, niż się spodziewasz, i zwykle jest to pomyłka, a nie zamiar. Jeśli Twój wzór „prawie działa, ale co drugi raz jest odwrotnie", policz wartości.
Zakończenia zmieniają wszystko
Druga niespodzianka wynika z poprzedniej lekcji. stroke-linecap dotyczy każdej kreski z osobna, nie tylko końców całej linii.
Przy round albo square każda kreska zostaje wydłużona o połowę grubości linii z obu stron. Przy grubości 10 i wzorze 12 8realne kreski mają długość 22, a przerwy zaledwie 8 — wzór wygląda zupełnie inaczej niż na papierze, bo policzyłeś kreski, a przeglądarka dołożyła do nich zakończenia.
Z tej samej właściwości bierze się jedna z najprzyjemniejszych sztuczek w SVG.
Kreska ustawiona na 0 przy zaokrąglonym zakończeniu daje linię z kropek. Kreska ma zerową długość i sama w sobie jest niewidoczna, ale zakończenia zostają — a dwa półkola sklejone ze sobą to koło. Przełącz zakończenie na
butti wszystko znika, bo nie ma czego zaokrąglać.
To jest właściwy sposób na kropkowaną linię: jedna ścieżka zamiast dwudziestu elementów <circle>. Odstęp między kropkami zmieniasz jedną liczbą, a średnicę przez stroke-width.
Kształty zamknięte i problem szwu
Na otwartej linii wzór po prostu urywa się na końcu i nikogo to nie obchodzi. Na kształcie zamkniętym — okręgu, prostokącie, obrysie ikony — wzór wraca do punktu startowego i tam prawie zawsze się nie schodzi.
Powód jest arytmetyczny. Obwód okręgu o promieniu 50 to około 314 jednostek. Wzór 12 8 ma cykl długości 20. Ponieważ 314 nie dzieli się przez 20, ostatnia kreska przed metą jest przycięta i przy punkcie startu widać zgrubienie albo szczerbę.
Są trzy wyjścia:
Dobrać wzór do obwodu. Policz obwód, podziel przez liczbę powtórzeń, jaką chcesz uzyskać. Skuteczne, ale przestaje działać, gdy zmienisz rozmiar kształtu.
Ukryć szew. Obrócić kształt tak, żeby styk wypadł w miejscu, którego nikt nie ogląda — na dole, pod innym elementem.
Użyć pathLength. Ten atrybut pozwala zadeklarować, że ścieżka „ma długość 100", niezależnie od jej prawdziwej długości. Wszystkie wartości dasharray i dashoffset są wtedy liczone w tej umownej skali, więc 50 50 zawsze da dokładnie połowę obwodu. To najczystsze rozwiązanie i wrócimy do niego w lekcji o animacji rysowania, bo tam jest wręcz niezbędne.
Gdzie to się przydaje naprawdę
Poza obramowaniami przerywanymi, które są oczywiste, dasharray obsługuje trzy rzeczy, o których nie pomyślałbyś od razu:
- Wskaźniki kołowe — pierścień postępu to okrąg, w którym kreska ma długość odpowiadającą procentowi, a przerwa resztę obwodu.
- Trasy na mapach — kropkowana linia lotu albo szlaku, jedna ścieżka zamiast setek punktów.
- Rysujące się linie — kreska równa całej długości ścieżki plus animowany
dashoffset, który ją odsłania. To temat lekcji 13 i najpopularniejszy efekt w całym SVG.
Podsumowanie
stroke-dasharrayprzyjmuje naprzemienne długości kresek i przerw, w jednostkach mierzonych wzdłuż ścieżki.- Nieparzysta liczba wartości jest automatycznie podwajana, przez co role kresek i przerw odwracają się w drugim cyklu.
stroke-dashoffsetprzesuwa cały wzór wzdłuż linii.stroke-linecapdotyczy każdej kreski osobno i wydłuża ją o połowę grubości z każdej strony.- Kreska o długości 0 z zaokrąglonym zakończeniem daje kropki.
- Na kształtach zamkniętych wzór rzadko schodzi się w punkcie startu;
pathLengthpozwala to obejść.
W następnej lekcji zostawiamy wygląd konturu i zajmujemy się przesuwaniem całych kształtów — a przy okazji faktem, że obrót w SVG kręci się wokół zupełnie innego punktu, niż większość osób zakłada.
Do wypróbowania: w presecie dash · kropki ustaw kreskę na 0, zakończenie na round, a potem zamień H 220 na łuk, na przykład A 100 60 0 0 1 220 40. Kropki ułożą się wzdłuż krzywej w równych odstępach — bo odległości są mierzone po ścieżce, a nie w poziomie.