Skip to content

Kõik WordPressist, veebiarendusest — ja mitte ainult

✨ SVG joonte ja suletud radade animeerimine puhta CSS-iga

✨ SVG joonte ja suletud radade animeerimine puhta CSS-iga

SVG-joonte animatsioon on üks neid tehnikaid, mis muudab staatilise ikooni elavaks illustratsiooniks. Oled seda efekti ilmselt näinud: logo piirjoon joonistab end sujuvalt, justkui jälgiks nähtamatu pliiats kujundit algusest lõpuni. See näeb kallis välja, kuid on tehtud puhta CSS-iga.

Probleem on selles, et enamik õpetusi peatub kõige lihtsama juhtumi juures: avatud tee, üks joon, animatsioon algusest lõpuni. Kuid päris graafika sisaldab suletud kontuure, katkendlikke kujundeid ja joonistamise suundi, mida disainer ei kontrollinud. SVG-tee võib alata ükskõik kust ja sul on vaja, et see joonistuks päripäeva esteetiliselt meeldivast alguspunktist.

Allpool on täielik tehnikate komplekt: alates põhianimatsioonist kuni topeltjoonte ning algus- ja lõpp-punktide täieliku kontrollini. Kõik puhtas CSS-is, ilma teekide või käitusaegsete mõõtmisteta. Neid meetodeid testiti SVG Divider pluginat arendades ja need töötavad igas kaasaegses brauseris.

💡 Kiirülevaade:

  • Leia SVG-tee pikkus getTotalLength() või Illustratori abil ja kirjuta number CSS-i.
  • Määra stroke-dasharray: LENGTH ja animeeri stroke-dashoffset väärtuselt LENGTH väärtusele 0.
  • Suuna muutmiseks vaheta tõmme ja vahe stroke-dasharray-s ning lükka stroke-dashoffset edasi.
  • Alguspunkti nihutamiseks lisa pool (või mis tahes osa) pikkusest stroke-dashoffset-ile.
  • Käivita „seest välja" animatsioon: alusta väärtuselt HALF_LENGTH, lõpeta väärtusel FULL_LENGTH.
  • Seadista topeltjooned poole pikkuse stroke-dasharray ja veerandnihkega stroke-dashoffset abil.

Tehniline alus: tõmbed, vahed ja tee pikkus

Iga SVG-animatsiooni tuumaks on kaks CSS-i omadust: stroke-dasharray ja stroke-dashoffset. Esimene määratleb „tõmbe-vahe" mustri piki kontuuri, teine nihutab seda mustrit. Kui teed tõmbe võrdseks kogu tee pikkusega ja seejärel animeerid nihke, siis joon „joonistub" su silme ees.

Võtmeetapp enne igasugust animatsiooni on kogu tee pikkuse leidmine. Meetodid:

  • JavaScript: document.querySelector('path').getTotalLength(), üks konsoolikutse, number läheb otse CSS-i sisse kodeeritult. Ei mingit käitusaega.
  • Illustrator: paneel „Dokumendi info" näitab valitud tee pikkust.
  • Kohandatud skript: kui sul on kümneid või sadu teid, on mõttekas kirjutada automaatne läbimine ja pikkuse märgistamine.

Oluline nüanss: getTotalLength() ja Illustrator võivad sama tee puhul anda veidi erinevad numbrid. Põhjuseks on erinev arvutustäpsus. Lahknevus jääb tavaliselt 1-2 ühiku piiresse ega mõjuta visuaali.

Kontrolli tee geomeetriat vigade suhtes. Joonistamise suund ja alguspunkt sõltuvad sellest, kuidas disainer kõvera redaktoris ehitas, see on normaalne. Allpool õpime mõlemat kontrollima ilma SVG-d ennast muutmata.

Põhianimatsioon: joone tõmbamine algusest lõpuni

Lihtsaim juhtum: avatud tee pikkusega, ütleme, 100 ühikut. Määra tõmme kogu pikkusele ja animeeri nihe 100-lt 0-le:

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}

Mis siin toimub: stroke-dasharray: 100 määrab 100 ühikut pidevat joont ja 100 ühikut tühja ruumi (teine väärtus on vaikimisi sama mis esimene). stroke-dashoffset: 100 nihutab mustrit nii, et nähtav osa läheb tee piiridest välja, joon on nähtamatu. Animatsioon vähendab nihke nullini ja tõmme roomab oma kohale.

Mõned praktilised märkused:

  • Asenda FULL_LENGTH tegeliku numbriga ilma mõõtühikuteta. CSS-i mootor ei mõista px ega em stroke-dasharray sees.
  • svg path selektor on ühe kontuuri jaoks. Kui SVG-l on mitu teed, kasuta klasse, ID-sid või pseudoklasse nagu path:nth-of-type(3). Silumise tööriistad: :nth Tester ja nthmaster.com.
  • @keyframes nimi peab olema iga animatsioonivariandi jaoks unikaalne. Erinevad teed vajavad sageli oma võtmekaadreid.
  • Väldi negatiivseid stroke-dashoffset väärtusi: Safari võib negatiivsete nihetega vilkuda või artefakte näidata.

Suuna kontrollimine: joonistamise ümberpööramine

Vaikimisi liigub animatsioon tee algusest lõpuni, ükskõik kuhu disainer kõvera joonistas. Kuid sageli on vaja vastupidist: suletud kontuur joonistub päripäeva, mitte vastupäeva.

Lahendus on tõmbemustri ümberpööramine: joon algab nähtamatuna (0 tõmmet, 100 vahet) ja muutub nähtavaks (100 tõmmet, 0 vahet), samal ajal kui nihe tõmbab seda tagurpidi:

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}

Mehaanika toimib tõmbemustri tsüklilise olemuse kaudu: pidev joon materialiseerub tee lõpus, samal ajal kui selle koopia läheb algusest vasakule ja jääb nähtamatuks. Sama juhtub suletud kontuuridel: tõmbe koopia ilmub „enne" algust ega sega tajumist.

On olemas alternatiivne lähenemine, lühem ja ilma massiiviga manipuleerimiseta:

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}

Siin on stroke-dasharray fikseeritud täispikkuses, samal ajal kui nihe liigub 100-lt 200-le. Sama tulemus, joon joonistub vastassuunas. Kasuta seda varianti, mis tundub sulle intuitiivsem.

Alguspunkti nihutamine

Suletud rada on nagu ringraudtee: rong võib alustada ükskõik millisest jaamast. Ülesanne on nihutada animatsiooni algus esteetiliselt meeldivasse punkti ilma geomeetriat ennast puudutamata.

Alustamine vastasküljelt

Sümmeetriliste kontuuride puhul piisab poole pikkuse nihkest:

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}

Joonistamise suund jääb originaalseks, kuid visuaalselt algab animatsioon vastasotsast.

Suuna muutmine ja suvaline alguspunkt

Et samaaegselt suunda muuta ja alguspunkti nihutada, lisa lõppnihkele täispikkus:

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äiesti suvalise punkti jaoks asenda 50 ükskõik millise väärtusega. Katse-eksituse meetodil (pluss-miinus 5-10 ühikut) leiad optimaalse positsiooni. Ühes projektis nihutati Twitchi bit-ikooni alguspunkti 17 piksli võrra, kole number, kuid visuaalselt täiuslik.

„Seest väljapoole" animatsioon

Joon kasvab keskelt mõlemas suunas korraga, klassikaline tehnika logode ja infograafika jaoks:

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}

Nihe algab poolelt pikkuselt (raja keskpunkt) ja liigub täispikkuseni, tõmmates joont kaasa. Asümmeetriliste kujundite puhul saab alguspunkti täiendavalt nihutada:

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}

Siin 84 = POOL_PIKKUST + 34. Konstant 34 on konkreetse kuju jaoks käsitsi valitud. Universaalset retsepti pole, proovi, vaata, kohenda.

„Väljast sissepoole" animatsioon: topeltpliiats

Vastupidine lähenemine: joon joonistub mõlemast otsast korraga, koondudes keskele. Avatud kontuuridel annab see „kahe pliiatsi" efekti:

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}

Joon ulatub vaid poole pikkuseni, tühimik kahaneb kaks korda kiiremini kui tavaanimatsioonis. stroke-dashoffset pole siin vajalik: lõppoleku „0 tühimik" muster ise paneb mõlemad joonepooled koonduma.

Täielik kontroll: algus- ja lõpp-punktid

Kui ühest suunast ja alguspunktist ei piisa, saad kontrollida mõlemat joonistuspiiri. Kaks liikuvat joonepead koonduvad ühisesse sihtpunkti:

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}

Väärtused 30 ja 80 on suvalised; ainus range reegel on, et from-nihe peab olema väiksem kui to-nihe. Kui punktid on lähestikku, lendab üks segment kiiresti, teine roomab aeglaselt, see on normaalne ja isegi ilus.

Ära karda minna to väärtusega täispikkusest kaugemale. stroke-dashoffset: 130 pikkusega 100 on lubatud, see lihtsalt nihutab joone tsükli teisele ringile. Peamine on vältida negatiivseid väärtusi.

Topeltjooned ja eriefektid

Kõige paindlikum režiim: poole pikkusega jooned veerandnihkega. Iga rada saab kaks iseseisvalt liikuvat joonepead:

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}

Keerukate kujundite puhul võib joonemassiiv koosneda mitmest komponendist. Kõigi massiivi väärtuste summa peaks võrduma täispikkusega. Reaalne näide lõpmatuse märgi jaoks:

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}

Neli massiivi komponenti (53 + 47 = 100 = täispikkus) vahetavad from ja to vahel kohti. Animatsioon kordub (infinite) ja pöördub tagasi (alternate), luues meditatiivse hingava kontuuri, mis ei kordu kunagi identselt.

Video: SVG-animatsioon praktikas

Et kõiki kirjeldatud tehnikaid reaalajas näha ja seadistamise nüansse mõista, vaata seda ingliskeelset õpetust:

Autor näitab samm-sammult animeeritud SVG-illustratsiooni loomist alates ekspordist Figmast kuni viimaste CSS-lihvideni. Kirjelduses olevad ajakoodid võimaldavad hüpata otse vajalikku sektsiooni.

⁉️🤔 Korduma kippuvad küsimused

Miks on vaja raja pikkust ette teada, kui olemas on getTotalLength()?

getTotalLength() on JavaScript ja meie eesmärk on puhas CSS ilma käitusaegsete sõltuvusteta. Mõõdad pikkuse ÜHE korra (konsoolis või Illustratoris), kodeerid numbri CSS-i ja animatsioon töötab ilma ühegi JS-reata.

Kas ühe animatsiooniga saab animeerida mitut rada?

Jah, kui neil on sama pikkus ja soovitud käitumine. Praktikas langevad rajad harva kokku, lihtsam on anda igale oma @keyframes või kasutada CSS-muutujaid erinevate pikkuse väärtustega.

Miks Safari vilgub negatiivse stroke-dashoffset väärtusega?

See on teadaolev WebKiti renderdusviga: negatiivseid nihke väärtusi tõlgendatakse mõnikord kui hetkelist nullimist. Lahendus on hoida stroke-dashoffset alati ≥ 0, kui vajad nihet, lisa täispikkus, selle asemel et negatiivseks minna.

Mida teha, kui animatsioon "tõmbleb" alguses või lõpus?

Lisa animation-ile forwards (säilitab lõppoleku) ja eemalda alternate, kui tagurdamist pole vaja. Kontrolli ka konflikte teiste sama elemendi CSS-reeglitega, näiteks transition sama omaduse kohta.

Kas see töötab stroke-dasharray'ga suletud kontuuridel keeruka geomeetriaga?

Jah, mehaanika on sama mis tahes SVG-radade, sirgjoonte, Bézier' kõverate, suletud polügoonide puhul. Ainus erinevus on see, et suletud kontuuril puudub visuaalne "algus" ja "lõpp", seega on alguspunkti kontrollimine esteetika seisukohast eriti oluline.

Kas animatsiooni tasub käsitsi kirjutada, kui olemas on teegid?

Lühike vastus: sõltub mastaabist. Ühekordse ikooni jaoks maandumislehel annab käsitsi juhtimine täiusliku tulemuse ilma lisasõltuvusteta. Viisteist minutit nihke seadistamist ja kontuur joonistub täpselt nii, nagu sa kavatsesid, mitte nii, nagu teegi arendaja otsustas.

Kui tegime SVG-jagajaid Elementorile, tasus käsitsi juhtimine end kolmekordselt ära. Plugin kasutab kümneid animeeritud jagajaid, igaüks individuaalselt häälestatud joontega. Ükski teek ei annaks sellist kontrolli esteetika üle.

Lisaks selle artikli tehnikatele saad kihiti lisada:

  • Animatsiooni oleku juhtimine JavaScripti kaudu (start/stopp/taaskäivitus);
  • Laisa käivitamise Intersection Observeri abil, kontuur joonistub alles siis, kui see jõuab vaatevälja;
  • Animatsiooniahelad animation-delay abil;
  • Kohandatud sujuvusfunktsioonid (cubic-bezier());
  • Täiendav läbipaistvuse töötlus @keyframes sees;
  • Katkendjoonte elastne animatsioon ("marssivad sipelgad").

Võta selle artikli plaanid aluseks, asenda oma pikkuse väärtused ja katseta cubic-bezier() funktsiooniga. Õigesti valitud sujuvusfunktsioon muudab animatsiooni tajumist rohkem kui alguspunkti nihutamine paari piksli võrra.