Išsamus vadovas žiniatinklio kūrėjams apie CSS slinktimi valdomų animacijų srauto kontrolę. Išmokite naudoti animation-direction su animation-timeline, kad sukurtumėte dinamiškas, kryptį jaučiančias vartotojo patirtis.
CSS slinktimi valdomų animacijų krypties įvaldymas: išsami srauto valdymo analizė
Ilgus metus animacijų, kurios reaguotų į vartotojo slinkties poziciją, kūrimas buvo JavaScript sritis. Bibliotekos, tokios kaip GSAP ir ScrollMagic, tapo esminiais įrankiais, tačiau dažnai tai kainuodavo našumo sąskaita, nes jos veikdavo pagrindinėje gijoje ir kartais sukeldavo trūkinėjančią patirtį. Žiniatinklio platforma evoliucionavo, ir šiandien mes turime revoliucinį, našų ir deklaratyvų sprendimą, integruotą tiesiai į naršyklę: CSS slinktimi valdomos animacijos.
Šis galingas naujas modulis leidžia mums tiesiogiai susieti animacijos progresą su konteinerio slinkties pozicija arba elemento matomumu peržiūros srityje. Nors tai yra milžiniškas šuolis į priekį, jis pristato naują mentalinį modelį. Vienas iš svarbiausių aspektų, kurį reikia įvaldyti, yra animacijos elgsenos valdymas, kai vartotojas slenka pirmyn, o ne atgal. Kaip padaryti, kad elementas animuotųsi slenkant žemyn, ir išsijungtų animacija slenkant atgal aukštyn? Atsakymas slypi pažįstamoje CSS savybėje, kuriai buvo suteikta nauja, galinga paskirtis: animation-direction.
Šis išsamus vadovas jus nuves į giluminę slinktimi valdomų animacijų srauto ir krypties valdymo analizę. Išnagrinėsime, kaip animation-direction yra pritaikoma naujai, išsiaiškinsime jos elgseną su praktiniais pavyzdžiais ir suteiksime jums žinių, reikalingų kuriant sudėtingas, kryptį jaučiančias vartotojo sąsajas, kurios atrodo intuityvios ir stulbinančios.
Slinktimi valdomų animacijų pagrindai
Prieš pradedant valdyti mūsų animacijų kryptį, pirmiausia turime suprasti pagrindinę mechaniką, kuri jas valdo. Jei ši tema jums nauja, šis skyrius pasitarnaus kaip svarbus įvadas. Jei jau esate susipažinę, tai puikus priminimas apie pagrindines veikiančias savybes.
Kas yra slinktimi valdomos animacijos?
Iš esmės, slinktimi valdoma animacija yra animacija, kurios progresas yra susietas ne su laikrodžiu (t. y., laiku), bet su slinkties laiko juostos progresu. Vietoj to, kad animacija truktų, tarkime, 2 sekundes, ji trunka visą slinkties veiksmo laiką.
Įsivaizduokite progreso juostą tinklaraščio įrašo viršuje. Tradiciškai, jūs naudotumėte JavaScript, kad klausytumėtės slinkties įvykių ir atnaujintumėte juostos plotį. Su slinktimi valdomomis animacijomis, galite tiesiog pasakyti naršyklei: „Susiekite šios progreso juostos plotį su viso puslapio slinkties pozicija.“ Tuomet naršyklė atlieka visus sudėtingus skaičiavimus ir atnaujinimus labai optimizuotu būdu, dažnai ne pagrindinėje gijoje, o tai užtikrina visiškai sklandžią animaciją.
Pagrindiniai privalumai yra:
- Našumas: Perduodant darbą iš pagrindinės gijos, išvengiame konfliktų su kitomis JavaScript užduotimis, o tai lemia sklandesnes, be trūkčiojimų animacijas.
- Paprastumas: Tai, kas anksčiau reikalavo dešimčių JavaScript eilučių, dabar galima pasiekti keliomis deklaratyvaus CSS eilutėmis.
- Pagerinta vartotojo patirtis: Animacijos, kurias tiesiogiai valdo vartotojo įvestis, atrodo labiau reaguojančios ir įtraukiančios, sukurdamos glaudesnį ryšį tarp vartotojo ir sąsajos.
Pagrindiniai veikėjai: `animation-timeline` ir laiko juostos
Magija yra valdoma animation-timeline savybės, kuri nurodo animacijai sekti slinkties progresą vietoj laikrodžio. Yra du pagrindiniai laiko juostų tipai, su kuriais susidursite:
1. Slinkties progreso laiko juosta (Scroll Progress Timeline): Ši laiko juosta yra susieta su slinkties pozicija slinkties konteineryje. Ji seka progresą nuo slinkties diapazono pradžios (0%) iki pabaigos (100%).
Tai apibrėžiama naudojant scroll() funkciją:
animation-timeline: scroll(root); — Seka dokumento peržiūros srities (numatytojo slankiklio) slinkties poziciją.
animation-timeline: scroll(nearest); — Seka artimiausio protėvinio slinkties konteinerio slinkties poziciją.
Pavyzdys: Paprasta skaitymo progreso juosta.
.progress-bar {
transform-origin: 0 50%;
transform: scaleX(0);
animation: fill-progress auto linear;
animation-timeline: scroll(root);
}
@keyframes fill-progress {
to { transform: scaleX(1); }
}
Čia fill-progress animacija yra valdoma bendro puslapio slinkimo. Kai slenkate iš viršaus į apačią, animacija progresuoja nuo 0% iki 100%, keisdama juostos mastelį nuo 0 iki 1.
2. Peržiūros progreso laiko juosta (View Progress Timeline): Ši laiko juosta yra susieta su elemento matomumu slinkties konteineryje (dažnai vadinamoje peržiūros sritimi). Ji seka elemento kelionę, kai jis įeina, kerta ir išeina iš peržiūros srities.
Tai apibrėžiama naudojant view() funkciją:
animation-timeline: view();
Pavyzdys: Elementas, kuris palaipsniui atsiranda, kai tampa matomas.
.reveal-on-scroll {
opacity: 0;
animation: fade-in auto linear;
animation-timeline: view();
}
@keyframes fade-in {
to { opacity: 1; }
}
Šiuo atveju fade-in animacija prasideda, kai elementas pradeda įeiti į peržiūros sritį, ir baigiasi, kai jis tampa visiškai matomas. Laiko juostos progresas yra tiesiogiai susietas su tuo matomumu.
Pagrindinė koncepcija: animacijos krypties valdymas
Dabar, kai suprantame pagrindus, atsakykime į pagrindinį klausimą: kaip priversti šias animacijas reaguoti į slinkties kryptį? Vartotojas slenka žemyn, ir elementas palaipsniui atsiranda. Jis slenka atgal aukštyn, ir elementas turėtų palaipsniui išnykti. Ši dvikryptė elgsena yra būtina kuriant intuityvias sąsajas. Būtent čia animation-direction didingai sugrįžta.
Prisimenant `animation-direction`
Tradicinėse, laiku pagrįstose CSS animacijose, animation-direction kontroliuoja, kaip animacija progresuoja per savo kadrus per kelias iteracijas. Galbūt esate susipažinę su jos reikšmėmis:
normal: Kiekviename cikle grojama pirmyn nuo 0% iki 100%. (Numatytoji reikšmė)reverse: Kiekviename cikle grojama atgal nuo 100% iki 0%.alternate: Pirmajame cikle grojama pirmyn, antrajame – atgal ir t. t.alternate-reverse: Pirmajame cikle grojama atgal, antrajame – pirmyn ir t. t.
Kai pritaikote slinkties laiko juostą, „iteracijų“ ir „ciklų“ sąvokos iš esmės išnyksta, nes animacijos progresas yra tiesiogiai susietas su viena, ištisine laiko juosta (pvz., slenkant iš viršaus į apačią). Naršyklė išradingai pernaudoja animation-direction, kad apibrėžtų ryšį tarp laiko juostos progreso ir animacijos progreso.
Naujas mentalinis modelis: laiko juostos progresas prieš animacijos progresą
Norėdami tai tikrai suprasti, turite nustoti galvoti apie laiką ir pradėti galvoti apie laiko juostos progresą. Slinkties laiko juosta eina nuo 0% (slinkties srities viršus) iki 100% (slinkties srities apačia).
- Slinkimas žemyn/pirmyn: Didina laiko juostos progresą (pvz., nuo 10% iki 50%).
- Slinkimas aukštyn/atgal: Mažina laiko juostos progresą (pvz., nuo 50% iki 10%).
animation-direction dabar nurodo, kaip jūsų @keyframes yra susieti su šiuo laiko juostos progresu.
animation-direction: normal; (Numatytoji reikšmė)
Tai sukuria tiesioginį, 1 su 1 atvaizdavimą.
- Kai laiko juostos progresas yra 0%, animacija yra ties savo 0% kadru.
- Kai laiko juostos progresas yra 100%, animacija yra ties savo 100% kadru.
Taigi, kai slenkate žemyn, animacija grojama pirmyn. Kai slenkate aukštyn, laiko juostos progresas mažėja, todėl animacija efektyviai grojama atbulai. Tai ir yra magija! Dvikryptė elgsena yra integruota. Jums nereikia daryti nieko papildomai.
animation-direction: reverse;
Tai sukuria apverstą atvaizdavimą.
- Kai laiko juostos progresas yra 0%, animacija yra ties savo 100% kadru.
- Kai laiko juostos progresas yra 100%, animacija yra ties savo 0% kadru.
Tai reiškia, kad kai slenkate žemyn, animacija grojama atgal (nuo jos pabaigos būsenos iki pradžios būsenos). Kai slenkate aukštyn, laiko juostos progresas mažėja, o tai priverčia animaciją groti pirmyn (nuo jos pradžios būsenos link pabaigos būsenos).
Šis paprastas pakeitimas yra neįtikėtinai galingas. Pažiūrėkime, kaip tai veikia praktiškai.
Praktinis įgyvendinimas ir pavyzdžiai
Teorija yra puiku, bet sukurkime keletą realaus pasaulio pavyzdžių, kad įtvirtintume šias koncepcijas. Daugumai jų naudosime view() laiko juostą, nes ji dažnai naudojama su vartotojo sąsajos elementais, kurie animuojasi pasirodydami ekrane.
1 Scenarijus: Klasikinis „atskleidimo slenkant“ efektas
Tikslas: Elementas palaipsniui atsiranda ir pasislenka aukštyn, kai slenkate žemyn į jo matymo lauką. Kai slenkate atgal aukštyn, jis turėtų palaipsniui išnykti ir pasislinkti atgal žemyn.
Tai yra labiausiai paplitęs naudojimo atvejis, ir jis puikiai veikia su numatytąja normal kryptimi.
HTML:
<div class="content-box reveal">
<h3>Scroll Down</h3>
<p>This box animates into view.</p>
</div>
CSS:
@keyframes fade-and-slide-in {
from {
opacity: 0;
transform: translateY(50px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.reveal {
/* Start in the 'from' state of the animation */
opacity: 0;
animation: fade-and-slide-in linear forwards;
animation-timeline: view();
/* animation-direction: normal; is the default, so it's not needed */
}
Kaip tai veikia:
- Mes apibrėžiame kadrus pavadinimu
fade-and-slide-in, kurie perkelia elementą iš permatomos ir žemesnės padėties (translateY(50px)) į visiškai nepermatomą ir pradinę padėtį (translateY(0)). - Mes pritaikome šią animaciją mūsų
.revealelementui ir, kas svarbiausia, susiejame ją suview()laiko juosta. Taip pat naudojameanimation-fill-mode: forwards;, kad užtikrintume, jog elementas liks galutinėje būsenoje pasibaigus laiko juostai. - Kadangi kryptis yra
normal, kai elementas pradeda įeiti į peržiūros sritį (laiko juostos progresas > 0%), animacija pradeda groti pirmyn. - Kai slenkate žemyn, elementas tampa labiau matomas, laiko juostos progresas didėja, o animacija juda link savo `to` būsenos.
- Jei slenkate atgal aukštyn, elementas tampa mažiau matomas, laiko juostos progresas *mažėja*, ir naršyklė automatiškai apverčia animaciją, priversdama jį išnykti ir pasislinkti žemyn. Jūs gaunate dvikryptį valdymą nemokamai!
2 Scenarijus: „Atsukimo“ arba „surinkimo“ efektas
Tikslas: Elementas prasideda dekonstruotoje arba galutinėje būsenoje, ir slenkant žemyn, jis animuojasi į savo pradinę, surinktą būseną.
Tai puikus animation-direction: reverse; naudojimo atvejis. Įsivaizduokite antraštę, kurios raidės pradžioje yra išbarstytos ir susirenka kartu, kai slenkate.
HTML:
<h1 class="title-reassemble">
<span>H</span><span>E</span><span>L</span><span>L</span><span>O</span>
</h1>
CSS:
@keyframes scatter-letters {
from {
/* Assembled state */
transform: translate(0, 0) rotate(0);
opacity: 1;
}
to {
/* Scattered state */
transform: translate(var(--x), var(--y)) rotate(360deg);
opacity: 0;
}
}
.title-reassemble span {
display: inline-block;
animation: scatter-letters linear forwards;
animation-timeline: view(block);
animation-direction: reverse; /* The key ingredient! */
}
/* Assign random end-positions for each letter */
.title-reassemble span:nth-child(1) { --x: -150px; --y: 50px; }
.title-reassemble span:nth-child(2) { --x: 80px; --y: -40px; }
/* ... and so on for other letters */
Kaip tai veikia:
- Mūsų kadrai,
scatter-letters, apibrėžia animaciją nuo surinktos būsenos (`from`) iki išbarstytos būsenos (`to`). - Mes pritaikome šią animaciją kiekvienai raidės `span` daliai ir susiejame ją su
view()laiko juosta. - Mes nustatome
animation-direction: reverse;. Tai apverčia atvaizdavimą. - Kai antraštė yra už ekrano ribų (laiko juostos progresas yra 0%), animacija yra priversta pereiti į savo 100% būseną (`to` kadras), todėl raidės yra išbarstytos ir nematomos.
- Kai slenkate žemyn ir antraštė patenka į peržiūros sritį, laiko juosta progresuoja link 100%. Kadangi kryptis yra apversta, animacija grojama nuo savo 100% kadro *atgal* link savo 0% kadro.
- Rezultatas: raidės suskrenda ir susirenka, kai slenkate į matymo lauką. Slinkimas atgal aukštyn vėl jas išbarsto.
3 Scenarijus: Dvikryptis sukimasis
Tikslas: Krumpliaračio piktograma sukasi pagal laikrodžio rodyklę slenkant žemyn ir prieš laikrodžio rodyklę slenkant aukštyn.
Tai dar vienas paprastas numatytosios normal krypties pritaikymas.
HTML:
<div class="icon-container">
<img src="gear.svg" class="spinning-gear" alt="Spinning gear icon" />
</div>
CSS:
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinning-gear {
animation: spin linear;
/* Attach to the whole document scroll for a continuous effect */
animation-timeline: scroll(root);
}
Kaip tai veikia:
Kai slenkate puslapiu žemyn, pagrindinė slinkties laiko juosta progresuoja nuo 0% iki 100%. Su normal animacijos kryptimi, tai tiesiogiai atitinka spin kadrus, priverčiant krumpliaratį suktis nuo 0 iki 360 laipsnių (pagal laikrodžio rodyklę). Kai slenkate atgal aukštyn, laiko juostos progresas mažėja, o animacija grojama atbulai, priverčiant krumpliaratį suktis nuo 360 atgal iki 0 laipsnių (prieš laikrodžio rodyklę). Tai elegantiškai paprasta.
Pažangios srauto valdymo technikos
Įvaldyti normal ir reverse yra 90% darbo. Bet norint iš tikrųjų atskleisti kūrybinį potencialą, reikia derinti krypties valdymą su laiko juostos diapazono valdymu.
Laiko juostos valdymas: `animation-range`
Pagal numatytuosius nustatymus, view() laiko juosta prasideda, kai elementas („subjektas“) patenka į slinkties sritį, ir baigiasi, kai jis visiškai ją praeina. animation-range-* savybės leidžia jums iš naujo apibrėžti šį pradžios ir pabaigos tašką.
animation-range-start: [phase] [offset];
animation-range-end: [phase] [offset];
`phase` gali būti reikšmės kaip:
entry: momentas, kai subjektas pradeda patekti į slinkties sritį.cover: momentas, kai subjektas yra visiškai slinkties srityje.contain: momentas, kai subjektas visiškai apima slinkties sritį (dideliems elementams).exit: momentas, kai subjektas pradeda išeiti iš slinkties srities.
Patobulinkime mūsų „atskleidimo slenkant“ pavyzdį. O kas, jei norime, kad jis animuotųsi tik tada, kai yra ekrano viduryje?
CSS:
.reveal-in-middle {
animation: fade-and-slide-in linear forwards;
animation-timeline: view();
animation-direction: normal;
/* New additions for range control */
animation-range-start: entry 25%;
animation-range-end: exit 75%;
}
Kaip tai veikia:
animation-range-start: entry 25%;reiškia, kad animacija (ir jos laiko juosta) neprasidėsentryfazės pradžioje. Ji lauks, kol elementas bus 25% kelio į peržiūros sritį.animation-range-end: exit 75%;reiškia, kad animacija bus laikoma 100% baigta, kai elementui liks tik 75% savęs, prieš visiškai išeinant.- Tai efektyviai sukuria mažesnę „aktyvią zoną“ animacijai peržiūros srities viduryje. Animacija vyks greičiau ir labiau centralizuotai. Krypties elgsena vis dar puikiai veikia šiame naujame, apribotame diapazone.
Mąstymas laiko juostos progresu: vienijanti teorija
Jei kada nors susipainiojate, grįžkite prie šio pagrindinio modelio:
- Apibrėžkite laiko juostą: Ar sekate visą puslapį (
scroll()), ar elemento matomumą (view())? - Apibrėžkite diapazoną: Kada ši laiko juosta prasideda (0%) ir baigiasi (100%)? (Naudojant
animation-range). - Susiekite animaciją: Kaip jūsų kadrai susieti su tuo 0%-100% laiko juostos progresu? (Naudojant
animation-direction).
normal: 0% laiko juostos -> 0% kadrų.reverse: 0% laiko juostos -> 100% kadrų.
Slinkimas pirmyn didina laiko juostos progresą. Slinkimas atgal jį mažina. Viskas kita išplaukia iš šių paprastų taisyklių.
Naršyklių palaikymas, našumas ir gerosios praktikos
Kaip ir su bet kuria pažangia žiniatinklio technologija, svarbu atsižvelgti į praktinius įgyvendinimo aspektus.
Dabartinis naršyklių palaikymas
Nuo 2023 m. pabaigos CSS slinktimi valdomos animacijos yra palaikomos Chromium pagrindu veikiančiose naršyklėse (Chrome, Edge) ir yra aktyviai kuriamos Firefox ir Safari. Visada patikrinkite naujausius šaltinius, tokius kaip CanIUse.com, norėdami gauti naujausią palaikymo informaciją.
Kol kas šios animacijos turėtų būti traktuojamos kaip progresyvus patobulinimas. Svetainė turi būti visiškai funkcionali ir be jų. Galite naudoti @supports taisyklę, kad jas pritaikytumėte tik tose naršyklėse, kurios supranta sintaksę:
/* Default styles for all browsers */
.reveal {
opacity: 1;
transform: translateY(0);
}
/* Apply animations only if supported */
@supports (animation-timeline: view()) {
.reveal {
opacity: 0; /* Set initial state for animation */
animation: fade-and-slide-in linear forwards;
animation-timeline: view();
}
}
Našumo aspektai
Didžiausias šios technologijos laimėjimas yra našumas. Tačiau ši nauda visiškai realizuojama tik tada, kai animuojate tinkamas savybes. Siekdami kuo sklandesnės patirties, laikykitės animuojamų savybių, kurias gali apdoroti naršyklės kompozitoriaus gija ir kurios nesukelia maketo perskaičiavimo ar perpiešimo.
- Puikūs pasirinkimai:
transform,opacity. - Naudoti atsargiai:
color,background-color. - Vengti, jei įmanoma:
width,height,margin,top,left(savybės, kurios veikia kitų elementų maketą).
Prieinamumo gerosios praktikos
Animacija prideda žavesio, tačiau ji gali blaškyti ar net pakenkti kai kuriems vartotojams, ypač tiems, kurie turi vestibiuliarinio aparato sutrikimų. Visada gerbkite vartotojo pageidavimus.
Naudokite prefers-reduced-motion medijos užklausą, kad išjungtumėte arba sušvelnintumėte savo animacijas.
@media (prefers-reduced-motion: reduce) {
.reveal, .spinning-gear, .title-reassemble span {
animation: none;
opacity: 1; /* Ensure elements are visible by default */
transform: none; /* Reset any transforms */
}
}
Be to, įsitikinkite, kad animacijos yra dekoratyvinės ir neperteikia svarbios informacijos, kuri nėra prieinama kitu būdu.
Išvada
CSS slinktimi valdomos animacijos reiškia paradigmos pokytį, kaip kuriame dinamiškas žiniatinklio sąsajas. Perduodami animacijos valdymą iš JavaScript į CSS, mes gauname milžinišką našumo naudą ir deklaratyvesnį, lengviau prižiūrimą kodą.
Raktas į jų visiško potencialo atskleidimą slypi srauto valdymo supratime ir įvaldymu. Iš naujo įsivaizduodami animation-direction savybę ne kaip iteracijų valdiklį, o kaip laiko juostos progreso ir animacijos progreso atvaizduotoją, mes gauname lengvą dvikryptį valdymą. Numatytasis normal elgesys suteikia labiausiai paplitusį modelį – animacija pirmyn slenkant pirmyn ir atgal slenkant atgal – o reverse suteikia mums galią kurti įtikinamus „atšaukimo“ ar „atsukimo“ efektus.
Naršyklių palaikymui toliau augant, šios technikos iš progresyvaus patobulinimo taps esminiu įgūdžiu šiuolaikiniams frontend kūrėjams. Taigi pradėkite eksperimentuoti šiandien. Permąstykite savo slinktimi pagrįstas sąveikas ir pamatykite, kaip galite pakeisti sudėtingą JavaScript keliomis elegantiško, našaus ir kryptį jaučiančio CSS eilutėmis.