Skip to content

Kaikki WordPressistä, web-kehityksestä — ja paljon muuta

✨ Svg-viivojen ja suljettujen polkujen animointi pelkällä css:llä

✨ Svg-viivojen ja suljettujen polkujen animointi pelkällä css:llä

SVG-viiva-animaatio on yksi niistä tekniikoista, jotka muuttavat staattisen kuvakkeen eläväksi kuvitukseksi. Olet luultavasti nähnyt tämän efektin: logon ääriviiva piirtyy sulavasti itsekseen, kuin näkymätön kynä jäljentäisi muodon alusta loppuun. Se näyttää kalliilta, mutta se tehdään pelkällä CSS:llä.

Ongelmana on, että useimmat tutoriaalit pysähtyvät yksinkertaisimpaan tapaukseen: avoin polku, yksi viiva, animaatio alusta loppuun. Oikea grafiikka sisältää kuitenkin suljettuja ääriviivoja, rikkonaisia muotoja ja piirtosuuntia, joita suunnittelija ei hallinnut. SVG-polku voi alkaa mistä tahansa, ja sinun tarvitsee saada se piirtymään myötäpäivään esteettisesti miellyttävästä aloituspisteestä.

Alla on täydellinen tekniikkasarja: perusanimaatiosta kaksoisviivoihin ja aloitus- ja lopetuspisteiden täyteen hallintaan. Kaikki puhtaalla CSS:llä, ei kirjastoja tai ajonaikaisia mittauksia. Nämä menetelmät testattiin SVG Divider -lisäosaa kehitettäessä ja ne toimivat kaikissa moderneissa selaimissa.

💡 Pikakatsaus:

  • Selvitä SVG-polun pituus getTotalLength()-metodilla tai Illustratorilla ja kirjoita luku CSS:ään.
  • Aseta stroke-dasharray: LENGTH ja animoi stroke-dashoffset arvosta LENGTH arvoon 0.
  • Kääntääksesi suunnan, vaihda viiva ja väli stroke-dasharray-arvossa ja työnnä stroke-dashoffset-arvoa eteenpäin.
  • Siirrä aloituspistettä lisäämällä puolet (tai mikä tahansa osuus) pituudesta stroke-dashoffset-arvoon.
  • Käynnistä "sisältä ulos" -animaatio: aloita arvosta HALF_LENGTH, lopeta arvoon FULL_LENGTH.
  • Määritä kaksoisviivat puolen pituuden stroke-dasharray-arvolla ja neljännespituuden siirrolla stroke-dashoffset-arvossa.

Tekninen perusta: viivat, välit ja polun pituus

Minkä tahansa SVG-animaation ytimessä on kaksi CSS-ominaisuutta: stroke-dasharray ja stroke-dashoffset. Ensimmäinen määrittelee "viiva-väli"-kuvion ääriviivaa pitkin, toinen siirtää tätä kuviota. Jos teet viivasta koko polun pituisen ja sitten animoit siirtymää, viiva "piirtyy" silmiesi edessä.

Keskeinen vaihe ennen mitään animaatiota on koko polun pituuden selvittäminen. Menetelmät:

  • JavaScript: document.querySelector('path').getTotalLength(), yksi konsolikutsu, numero kovakoodataan CSS:ään. Ei ajonaikaista suoritusta.
  • Illustrator: "Asiakirjan tiedot" -paneeli näyttää valitun polun pituuden.
  • Oma skripti: jos sinulla on kymmeniä tai satoja polkuja, on järkevää kirjoittaa automaattinen läpikäynti ja pituusmerkintä.

Tärkeä vivahde: getTotalLength() ja Illustrator voivat antaa hieman eri lukuja samalle polulle. Syynä on erilainen laskentatarkkuus. Ero on yleensä 1-2 yksikön sisällä, eikä se vaikuta visuaaliseen ilmeeseen.

Tarkista polun geometria virheiden varalta. Piirtosuunta ja aloituspiste riippuvat siitä, miten suunnittelija rakensi käyrän editorissa, se on normaalia. Alla opimme hallitsemaan molempia muokkaamatta itse SVG:tä.

Perusanimaatio: viivan piirtäminen alusta loppuun

Yksinkertaisin tapaus: avoin polku, jonka pituus on vaikkapa 100 yksikköä. Aseta viiva koko pituudelle ja animoi siirtymä 100:sta 0:aan:

1@keyframes reveal {
2 to {
3 stroke-dashoffset: 0;
4 }
5}
6svg path {
7 stroke-dashoffset: 100;
8 stroke-dasharray: 100;
9 animation: reveal 1s ease-in-out 0s forwards;
10}

Mitä tässä tapahtuu: stroke-dasharray: 100 asettaa 100 yksikköä yhtenäistä viivaa ja 100 yksikköä tyhjää tilaa (toinen arvo oletusarvoisesti sama kuin ensimmäinen). stroke-dashoffset: 100 siirtää kuviota niin, että näkyvä osa menee polun rajojen ulkopuolelle, viiva on näkymätön. Animaatio pienentää siirtymän nollaan, ja viiva ryömii paikalleen.

Muutama käytännön huomio:

  • Korvaa FULL_LENGTH todellisella numerolla ilman mittayksikköä. CSS-moottori ei ymmärrä px- tai em-yksiköitä stroke-dasharray-arvon sisällä.
  • svg path -valitsin on yhdelle ääriviivalle. Jos SVG:ssä on useita polkuja, käytä luokkia, ID:itä tai pseudoluokkia, kuten path:nth-of-type(3). Debuggaustyökalut: :nth Tester ja nthmaster.com.
  • @keyframes-nimen on oltava yksilöllinen jokaiselle animaatiovariantille. Eri polut vaativat usein omat keyframes-kehyksensä.
  • Vältä negatiivisia stroke-dashoffset-arvoja: Safari saattaa välkkyä tai näyttää artefakteja negatiivisilla siirtymillä.

Suunnan hallinta: piirtosuunnan kääntäminen

Oletusarvoisesti animaatio kulkee polun alusta loppuun, minne suunnittelija sitten käyrän piirsikin. Mutta usein tarvitset päinvastaista: suljettu ääriviiva piirtyy myötäpäivään vastapäivän sijaan.

Ratkaisu on kääntää viivakuvio: viiva alkaa näkymättömänä (0 viivaa, 100 väliä) ja muuttuu näkyväksi (100 viivaa, 0 väliä), samalla kun siirtymä vetää sitä taaksepäin:

1@keyframes reversed {
2 from {
3 stroke-dasharray: 0 100;
4 stroke-dashoffset: 0;
5 }
6 to {
7 stroke-dasharray: 100 0;
8 stroke-dashoffset: 100;
9 }
10}
11svg path {
12 animation: reversed 1s ease-in-out 0s forwards;
13}

Mekaniikka toimii viivakuvion syklisen luonteen kautta: yhtenäinen viiva ilmestyy polun loppuun, kun taas sen kopio menee vasemmalle alun ohi ja pysyy näkymättömänä. Sama tapahtuu suljetuilla ääriviivoilla: viivan kopio ilmestyy "ennen" alkua eikä häiritse havaintoa.

On olemassa vaihtoehtoinen lähestymistapa, lyhyempi ja ilman taulukon manipulointia:

1@keyframes alternative-reversed {
2 from {
3 stroke-dashoffset: 100;
4 }
5 to {
6 stroke-dashoffset: 200;
7 }
8}
9svg path {
10 stroke-dasharray: 100;
11 animation: alternative-reversed 1s ease-in-out 0s forwards;
12}

Tässä stroke-dasharray on kiinteästi koko pituudella, kun taas offset siirtyy 100:sta 200:aan. Sama lopputulos, viiva piirtyy käänteiseen suuntaan. Käytä sitä versiota, joka tuntuu sinusta intuitiivisemmalta.

Aloituskohdan siirtäminen

Suljettu polku on kuin ympyrän muotoinen rautatie: juna voi lähteä miltä asemalta tahansa. Tehtävänä on siirtää animaation alku esteettisesti miellyttävään kohtaan koskematta itse geometriaan.

Aloitus vastakkaiselta puolelta

Symmetrisillä ääriviivoilla puolen pituuden offset riittää:

1@keyframes start-from-other-side {
2 from {
3 stroke-dasharray: 0 100;
4 stroke-dashoffset: 50;
5 }
6 to {
7 stroke-dasharray: 100 0;
8 stroke-dashoffset: 50;
9 }
10}
11svg path {
12 animation: start-from-other-side 1s ease-in-out 0s forwards;
13}

Piirtosuunta pysyy alkuperäisenä, mutta visuaalisesti animaatio alkaa vastakkaisesta päästä.

Suunnan kääntäminen ja mielivaltainen alku

Jos haluat samanaikaisesti kääntää suunnan ja siirtää aloituskohtaa, lisää koko pituus lopulliseen offsetiin:

1@keyframes other-side-and-reverse {
2 from {
3 stroke-dasharray: 0 100;
4 stroke-dashoffset: 50;
5 }
6 to {
7 stroke-dasharray: 100 0;
8 stroke-dashoffset: 150;
9 }
10}
11svg path {
12 animation: other-side-and-reverse 1s ease-in-out 0s forwards;
13}

Täysin mielivaltaiseen kohtaan voit korvata arvon 50 millä tahansa muulla arvolla. Kokeilemalla (plus tai miinus 5-10 yksikköä) löydät optimaalisen kohdan. Yhdessä projektissa Twitch-bittikuvakkeen aloituskohtaa siirrettiin 17 pikseliä, ruma luku mutta visuaalisesti täydellinen.

"Sisältä ulos" -animaatio

Viiva kasvaa keskeltä molempiin suuntiin samanaikaisesti, klassinen tekniikka logoille ja infografiikoille:

1@keyframes inside-out {
2 from {
3 stroke-dasharray: 0 100;
4 stroke-dashoffset: 50;
5 }
6 to {
7 stroke-dasharray: 100 0;
8 stroke-dashoffset: 100;
9 }
10}
11svg path {
12 animation: inside-out 1s ease-in-out 0s forwards;
13}

Offset alkaa puolesta pituudesta (polun keskipiste) ja etenee koko pituuteen vetäen viivaa mukanaan. Epäsymmetrisillä muodoilla aloituskohtaa voidaan siirtää lisää:

1@keyframes custom-inside-out {
2 from {
3 stroke-dasharray: 0 100;
4 stroke-dashoffset: 84;
5 }
6 to {
7 stroke-dasharray: 100 0;
8 stroke-dashoffset: 134;
9 }
10}

Tässä 84 = PUOLIKAS_PITUUS + 34. Vakio 34 on valittu käsin tiettyä muotoa varten. Yleispätevää reseptiä ei ole, kokeile, katso, säädä.

"Ulkoa sisään" -animaatio: kaksoiskynä

Päinvastainen lähestymistapa: viiva piirtyy molemmista päistä samanaikaisesti, kohdaten keskellä. Avoimilla ääriviivoilla tämä antaa "kahden kynän" efektin:

1@keyframes outside-in {
2 from {
3 stroke-dasharray: 0 100;
4 }
5 to {
6 stroke-dasharray: 50 0;
7 }
8}
9svg path {
10 animation: outside-in 1s ease-in-out 0s forwards;
11}

Viiva kattaa vain puolet pituudesta, ja aukko kutistuu kaksi kertaa nopeammin kuin perusanimaatiossa. stroke-dashoffset-arvoa ei tarvita tässä: "0 aukko" -kuvio lopputilassa itsessään saa molemmat viivan puolikkaat kohtaamaan.

Täysi hallinta: aloitus- ja lopetuspisteet

Kun yksi suunta ja aloituspiste eivät riitä, voit hallita molempia piirtorajoja. Kaksi liikkuvaa viivan päätä kohtaavat yhteisessä määränpäässä:

1@keyframes custom-start-end {
2 from {
3 stroke-dasharray: 0 100;
4 stroke-dashoffset: 30;
5 }
6 to {
7 stroke-dasharray: 100 0;
8 stroke-dashoffset: 80;
9 }
10}
11svg path {
12 animation: custom-start-end 1s ease-in-out 0s forwards;
13}

Arvot 30 ja 80 ovat mielivaltaisia; from-offset pienempi kuin to-offset on ainoa ehdoton sääntö. Jos pisteet ovat lähellä toisiaan, yksi segmentti lentää nopeasti, toinen matelee hitaasti, se on normaalia ja jopa kaunista.

Älä pelkää ylittää koko pituutta to-arvossa. stroke-dashoffset: 130 pituudella 100 on sallittu, se vain siirtää viivasyklin toiselle kierrokselle. Pääasia on välttää negatiivisia arvoja.

Kaksoisviivat ja erikoistehosteet

Joustavin tila: puolen pituuden viivat neljännessiirrolla. Jokainen polku saa kaksi viivan päätä, jotka liikkuvat itsenäisesti:

1@keyframes double-lines {
2 from {
3 stroke-dasharray: 0 50;
4 stroke-dashoffset: 25;
5 }
6 to {
7 stroke-dasharray: 50 0;
8 stroke-dashoffset: 50;
9 }
10}
11svg path {
12 animation: double-lines 1s ease-in-out 0s forwards;
13}

Monimutkaisilla muodoilla viivataulukko voi koostua useista komponenteista. Kaikkien taulukon arvojen summan tulee olla yhtä suuri kuin koko pituus. Todellinen esimerkki äärettömyysmerkille:

1@keyframes infinity-double-lines {
2 from {
3 stroke-dasharray: 0 53 0 47;
4 stroke-dashoffset: 37;
5 }
6 to {
7 stroke-dasharray: 53 0 47 0;
8 stroke-dashoffset: 60;
9 }
10}
11svg .infinity {
12 animation: infinity-double-lines 8s ease-in-out 0s alternate infinite;
13 stroke: #8D69D8;
14}

Neljä taulukkokomponenttia (53 + 47 = 100 = koko pituus) vaihtavat paikkoja from- ja to-arvojen välillä. Animaatio toistuu silmukassa (infinite) ja kääntyy (alternate), luoden meditatiivisen hengittävän ääriviivan, joka ei koskaan toistu samanlaisena.

Video: SVG-animaatio käytännössä

Jos haluat nähdä kaikki kuvatut tekniikat livenä ja ymmärtää asetusten vivahteet, katso tämä englanninkielinen opasvideo:

Videon tekijä näyttää vaihe vaiheelta animoidun SVG-kuvituksen luomisen viennistä Figmasta lopullisiin CSS-viilauksiin. Kuvauksen aikakoodien avulla voit hypätä suoraan tarvitsemaasi kohtaan.

⁉️🤔 Usein kysytyt kysymykset

Miksi polun pituus pitää tietää etukäteen, vaikka käytössä on getTotalLength()?

getTotalLength() on JavaScriptiä, ja tavoitteemme on puhdas CSS ilman ajonaikaisia riippuvuuksia. Mittaat pituuden KERRAN (konsolissa tai Illustratorissa), kovakoodaat luvun CSS:ään, ja animaatio toimii ilman yhtäkään JavaScript-riviä.

Voiko yhdellä animaatiolla animoida useita polkuja?

Kyllä, jos niillä on sama pituus ja haluttu käyttäytyminen. Käytännössä polut harvoin täsmäävät, on helpompaa antaa kullekin oma @keyframes tai käyttää CSS-muuttujia eri pituusarvoilla.

Miksi Safari välkkyy negatiivisella stroke-dashoffset-arvolla?

Kyseessä on tunnettu WebKit-renderöintibugi: negatiiviset offset-arvot tulkitaan joskus välittömäksi nollaukseen. Korjaus on pitää stroke-dashoffset aina ≥ 0, jos tarvitset siirtymää, lisää koko pituus sen sijaan, että menisit negatiiviseksi.

Mitä tehdä, jos animaatio "nykii" alussa tai lopussa?

Lisää forwards animation-määreeseen (säilyttää lopputilan) ja poista alternate, jos et tarvitse suunnanvaihtoa. Tarkista myös ristiriidat saman elementin muiden CSS-sääntöjen kanssa, esimerkiksi transition samalle ominaisuudelle.

Toimiiko tämä stroke-dasharray suljetuilla, monimutkaisen geometrian omaavilla muodoilla?

Kyllä, mekaniikka on sama kaikille SVG-poluille, suorille viivoille, Bezier-käyrille, suljetuille polygoneille. Ainoa ero on, että suljetulla muodolla ei ole visuaalista "alkua" ja "loppua", joten aloituspisteen hallinta on erityisen tärkeää estetiikan kannalta.

Kannattaako animaatio kirjoittaa käsin, kun tarjolla on kirjastoja?

Lyhyt vastaus: riippuu mittakaavasta. Yksittäiselle kuvakkeelle laskeutumissivulla käsin tehty ohjaus antaa täydellisen lopputuloksen ilman ylimääräisiä riippuvuuksia. Varttitunti offsetin säätöä, ja ääriviiva piirtyy juuri niin kuin tarkoitit, ei niin kuin kirjaston kehittäjä päätti.

Kun teimme SVG-jakajia Elementorille, käsin tehty ohjaus maksoi itsensä kolminkertaisesti takaisin. Lisäosa käyttää kymmeniä animoituja jakajia, joista jokaisessa on yksilöllisesti viritetyt viivat. Mikään kirjasto ei antaisi vastaavaa hallintaa estetiikkaan.

Tämän artikkelin tekniikoiden päälle voit kerrostaa:

  • Animaation tilan hallinnan JavaScriptin avulla (käynnistys/pysäytys/uudelleenkäynnistys);
  • Laiskan käynnistyksen Intersection Observerilla, ääriviiva piirtyy vasta, kun se tulee näkymään;
  • Animaatioketjut animation-delay-määreellä;
  • Mukautetut easing-funktiot (cubic-bezier());
  • Lisätyön läpinäkyvyyden kanssa @keyframes-määrittelyssä;
  • Katkoviivojen elastisen animaation ("marssivat muurahaiset").

Ota tämän artikkelin suunnitelmat pohjaksi, korvaa omat pituusarvosi ja kokeile cubic-bezier()-funktiota. Oikein valittu easing-funktio muuttaa animaation tuntua enemmän kuin aloituspisteen siirtäminen parilla pikselillä.