Animații receptive pentru fiecare dimensiune de ecran și dispozitiv PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Animații receptive pentru fiecare dimensiune de ecran și dispozitiv

Înainte de a începe cariera în dezvoltare, am făcut o grămadă de lucrări de grafică în mișcare în After Effects. Dar chiar și cu acest fundal, mi s-a părut încă destul de derutantă animarea pe web.

Grafica video este proiectată într-un anumit raport și apoi exportată. Terminat! Dar nu există „setări de export” pe web. Pur și simplu împingem codul în lume, iar animațiile noastre trebuie să se adapteze la orice dispozitiv pe care aterizează.

Deci haideți să vorbim despre animație receptivă! Cum abordăm cel mai bine animarea pe rețeaua sălbatică? Vom acoperi câteva abordări generale, câteva sfaturi specifice GSAP și câteva principii de mișcare. Să începem cu niște încadrare...

Cum va fi folosită această animație?

Articolul lui Zach Saucier despre animația responsive recomandă să faceți un pas înapoi pentru a vă gândi la rezultatul final înainte de a trece la cod.

Va fi animația un modul care se repetă în mai multe părți ale aplicației dvs.? Trebuie să se scaleze deloc? Ținând cont de acest lucru, puteți determina metoda în care o animație ar trebui să fie scalată și vă împiedică să pierdeți efort.

Acesta este un sfat grozav. A mare O parte a proiectării animației receptive este să știi dacă și cum trebuie să se extindă acea animație și apoi să alegi abordarea corectă de la început.

Majoritatea animațiilor se încadrează în următoarele categorii:

  • Fix: Animații pentru lucruri precum pictograme sau încărcătoare care păstrează aceeași dimensiune și raport de aspect pe toate dispozitivele. Nimic de care să vă faceți griji aici! Codificați câteva valori pixeli acolo și continuați-vă ziua.
  • Fluid: Animații care trebuie să se adapteze fluid pe diferite dispozitive. Majoritatea animațiilor de aspect se încadrează în această categorie.
  • Vizat: Animații care sunt specifice unui anumit dispozitiv sau dimensiune a ecranului sau se modifică substanțial la un anumit punct de întrerupere, cum ar fi animațiile doar pentru desktop sau interacțiunile care se bazează pe interacțiunea specifică dispozitivului, cum ar fi atingerea sau trecerea cursorului.

Animațiile fluide și direcționate necesită moduri diferite de gândire și soluții. Hai să aruncăm o privire…

Animație fluidă

As Andy Bell spune: Fii mentorul browser-ului, nu micromanagerul acestuia - da-i browser-ului câteva reguli și indicii solide, apoi lasă-l să ia deciziile potrivite pentru persoanele care îl vizitează. (Aici sunt toboganele din acea prezentare.)

Animația fluidă înseamnă a lăsa browserul să facă treaba grea. O mulțime de animații se pot adapta cu ușurință la diferite contexte doar folosind unitățile potrivite de la început. Dacă redimensionați acest stilou, puteți vedea că animația folosește unități de vizualizare se scalează fluid pe măsură ce browserul se ajustează:

Caseta violet chiar își schimbă lățimea la diferite puncte de întrerupere, dar, deoarece folosim procente pentru ao muta, animația se scalează și ea.

Animarea proprietăților de aspect, cum ar fi left și top poate provoca refluxuri ale aspectului și animație nervoasă, așa că, acolo unde este posibil, rămâneți la transformări și opacitate.

Totuși, nu ne limităm doar la aceste unități – haideți să aruncăm o privire la alte posibilități.

unități SVG

Unul dintre lucrurile pe care îmi place să lucrez cu SVG este că putem folosi unități de utilizator SVG pentru animație, care sunt receptive imediat. Indiciul este chiar în nume - Scalable Grafic vectorial. În SVG-land, toate elementele sunt reprezentate la anumite coordonate. Spațiul SVG este ca un fragment infinit de hârtie milimetrică în care putem aranja elemente. The viewBox definește dimensiunile hârtiei milimetrice pe care le putem vedea.

viewBox="0 0 100 50”

În următoarea demonstrație, SVG-ul nostru viewBox is 100 unități late și 50 unități înalte. Aceasta înseamnă că dacă animam elementul prin 100 unități de-a lungul axei x, se va mișca întotdeauna pe toată lățimea SVG-ului său părinte, indiferent cât de mare sau mic este acel SVG! Dați demonstrației o redimensionare pentru a vedea.

Animarea unui element copil pe baza lățimii unui container părinte este un mic truc în HTML-land. Până acum, a trebuit să luăm lățimea părintelui cu JavaScript, ceea ce este destul de ușor atunci când animați from o poziție transformată, dar puțin mai lăutărească când animați to undeva, după cum puteți vedea în demo-ul următor. Dacă punctul final este o poziție transformată și redimensionați ecranul, va trebui să ajustați manual acea poziție. Dezordonat... 🤔

Dacă ajustați valorile la redimensionare, nu uitați debota, sau chiar declanșați funcția după ce browserul a terminat de redimensionat. Ascultătorii redimensionați declanșează o mulțime de evenimente în fiecare secundă, așa că actualizarea proprietăților pentru fiecare eveniment este multă muncă pentru browser.

Dar, această viteză de animație va deveni în curând un lucru din trecut! Tulburare de tobe, vă rog... 🥁

Unități de containere! Chestii minunate. În momentul în care scriu acest lucru, funcționează doar în Chrome și Safari - dar poate până când veți citi asta, vom avea și Firefox. Vedeți-le în acțiune în următorul demo. Uită-te la băieții ăia! Nu este o animație interesantă, care este relativă la elementele părinte!

Datele de asistență ale acestui browser provin de la Pot folosi, care are mai multe detalii. Un număr indică faptul că browserul acceptă funcția la versiunea respectivă și mai sus.

Desktop

Chrome Firefox IE Margine Safari
105 Nu Nu 105 16.0

Mobil/Tabletă

Android-chrome Android Firefox Android Safari iOS
106 Nu 106 16.0

Tranziții fluide cu FLIP

După cum am menționat mai devreme, în SVG-land fiecare element este bine plasat pe o singură grilă și foarte ușor de mutat în mod receptiv. În HTML-land, este mult mai complex. Pentru a construi layout-uri receptive, folosim o mulțime de metode de poziționare și sisteme de layout diferite. Una dintre principalele dificultăți ale animației pe web este aceea mult de modificări ale aspectului sunt imposibil de animat. Poate că un element trebuie să se miște din poziție relative la fixed, sau unii copii ai unui container flexibil trebuie să fie amestecați fără probleme în jurul feței de vizualizare. Poate că un element trebuie chiar să fie re-parent și mutat într-o poziție complet nouă în DOM.

Delicat, nu?

Bine. Tehnica FLIP este aici pentru a salva ziua; ne permite să animam cu ușurință aceste lucruri imposibile. Premisa de bază este:

  • First: Prindeți poziția inițială a elementelor implicate în tranziție.
  • Nume: Mută ​​elementele și apucă poziția finală.
  • Inversa: Calculați schimbările dintre prima și ultima stare și aplicați transformări pentru a inversa elementele înapoi în poziția lor inițială. Acest lucru face să pară că elementele sunt încă în primul poziție, dar de fapt nu sunt.
  • Joaca: Eliminați transformările inversate și animați-le inscenat primul stare la ultimul de stat.

Iată o demonstrație care folosește pluginul FLIP de la GSAP, care face toate sarcinile pentru tine!

Dacă doriți să înțelegeți puțin mai multe despre implementarea vaniliei, mergeți la Paul Lewis blog — el este creierul din spatele tehnicii FLIP.

Scalare fluidă SVG

M-ai prins... asta nu este într-adevăr un sfat de animație. Dar aranjarea corectă a scenei este esențială pentru o bună animație! SVG se scalează foarte bine în mod implicit, dar putem controla modul în care se scalează și mai mult preserveAspectRatio, care este foarte util atunci când raportul de aspect al elementului SVG și viewBox raportul de aspect este diferit. Funcționează în același mod ca și background-position și background-size proprietăți în CSS. Declarația este alcătuită dintr-o valoare de aliniere (background-position) Și un Întâlni or Felie referinta (background-size).

În ceea ce privește acele referințe Meet și Slice - slice este ca background size: cover, și meet este ca background-size: contain.

  • preserveAspectRatio="MidYMax slice" — Aliniați-vă la mijlocul axei x, partea de jos a axei y și măriți-l pentru a acoperi întreaga zonă de vizualizare.
  • preserveAspectRatio="MinYMin meet" — Aliniați la stânga axei x, partea superioară a axei y și măriți în același timp păstrând întregul viewBox vizibil.

Tom Miller face acest lucru un pas mai departe utilizând overflow: visible în CSS și un element care conține „stage left” și „stage right” păstrând înălțimea limitată:

Pentru animațiile SVG receptive, poate fi util să utilizați caseta de vizualizare SVG pentru a crea o vizualizare care decupează și se scalează sub o anumită lățime a browserului, dezvăluind totodată mai multă animație SVG la dreapta și la stânga atunci când browserul este mai lat decât atât. prag. Putem realiza acest lucru adăugând overflow vizibil pe SVG și asociindu-l cu un max-height wrapper pentru a preveni scalarea prea mare a SVG-ului pe verticală.

Pânză la scară fluidă

Canvas este mult mai performant pentru animațiile complexe cu loturi de piese în mișcare decât animarea SVG sau HTML DOM, dar este în mod inerent și mai complex. Trebuie să muncești pentru acele câștiguri de performanță! Spre deosebire de SVG care are unități de răspuns minunate și scalare din cutie, trebuie să fie stăpânit și microgestionat puțin.

Îmi place să-mi instalez astfel încât funcționează în același mod ca SVG (pot fi părtinitor) cu un sistem de unități minunat în care să funcționeze și un raport de aspect fix. De asemenea, trebuie redesenat de fiecare dată când ceva se schimbă, așa că nu uitați să amânați redesenarea până când browserul termină redimensionarea sau retrage!

George Francis adunați și asta minunată bibliotecă care vă permite să definiți o pânză viewBox atribut și preserveAspectRatio — exact ca SVG!

Animație țintită

Uneori, poate fi necesar să adoptați o abordare mai puțin fluidă și mai direcționată a animației dvs. Dispozitivele mobile au mult mai puține proprietăți imobiliare și mai puține performanțe de animație decât o mașină desktop. Prin urmare, este logic să difuzați animație redusă utilizatorilor de telefonie mobilă, eventual chiar fără animație:

Uneori, cea mai bună animație receptivă pentru mobil nu este deloc animație! Pentru UX mobil, acordați prioritate permiterii utilizatorului să consume rapid conținut față de așteptarea ca animațiile să se termine. Animațiile mobile ar trebui să îmbunătățească conținutul, navigarea și interacțiunile, mai degrabă decât să le întârzie. Eric van Holtz

Pentru a face acest lucru, putem folosi interogări media pentru a viza anumite dimensiuni ale ferestrelor de vizualizare, așa cum facem atunci când facem stiluri cu CSS! Iată o demonstrație simplă care arată o animație CSS gestionată folosind interogări media și o animație GSAP gestionată cu gsap.matchMedia():

Simplitatea acestui demo ascunde o grămadă de magie! Animațiile JavaScript necesită puțin mai multă configurare și curățare pentru a funcționa corect doar la o dimensiune specifică a ecranului. Am văzut orori în trecut în care oamenii tocmai au ascuns animația din vedere în CSS cu opacity: 0, dar animația continuă să scadă în fundal folosind resurse. 😱

Dacă dimensiunea ecranului nu se mai potrivește, animația trebuie să fie eliminată și eliberată pentru colectarea gunoiului, iar elementele afectate de animație trebuie să fie eliminate de orice stiluri inline introduse de mișcare pentru a preveni conflictele cu alte stiluri. Până gsap.matchMedia(), acesta a fost un proces greoi. A trebuit să urmărim fiecare animație și să gestionăm toate acestea manual.

gsap.matchMedia() în schimb, vă permite să introduceți cu ușurință codul de animație într-o funcție care se execută numai atunci când o anumită interogare media chibrituri. Apoi, când nu se mai potrivește, toate animațiile GSAP și ScrollTriggers în acea funcție, reveniți automat. Interogarea media în care sunt introduse animațiile face toată munca grea pentru tine. Este în GSAP 3.11.0 și schimbă jocul!

Nu suntem constrânși doar la dimensiunile ecranului. Există o o mulțime de caracteristici media acolo pentru a te conecta!

(prefers-reduced-motion) /* find out if the user would prefer less animation */

(orientation: portrait) /* check the user's device orientation */

(max-resolution: 300dpi) /* check the pixel density of the device */

În următoarea demonstrație am adăugat o verificare pentru prefers-reduced-motion astfel încât toți utilizatorii cărora li se pare că animația este dezorientată să nu fie deranjat de lucrurile care zboară.

Și vezi cealaltă demonstrație distractivă a lui Tom Miller în care folosește raportul de aspect al dispozitivului pentru a ajusta animația:

Gândind în afara cutiei, dincolo de dimensiunile ecranului

Nu te gândești la animația receptivă decât doar dimensiunile ecranului. Dispozitivele diferite permit interacțiuni diferite și este ușor să intrați într-un pic de încurcătură atunci când nu luați în considerare acest lucru. Dacă creați stări de trecere cu mouse-ul în CSS, puteți utiliza hover caracteristică media pentru a testa dacă utilizatorul primar mecanismul de intrare poate trece peste elemente.

@media (hover: hover) {
 /* CSS hover state here */
}

Câteva sfaturi de la Jake Whiteley:

De multe ori ne bazăm animațiile pe lățimea browserului, făcând presupunerea naivă că utilizatorii de desktop doresc stări de hover. Am avut personal o mulțime de probleme în trecut în care aș trece la aspectul desktop>1024px, dar s-ar putea să fac detectarea atingerii în JS - ceea ce duce la o nepotrivire în care aspectul era pentru desktop-uri, dar JS era pentru telefoane mobile. În aceste zile, mă sprijin pe hover și indicator pentru a asigura paritatea și a manevra suprafețele iPad Pros sau Windows (care pot schimba tipul de indicator în funcție de dacă capacul este jos sau nu)

/* any touch device: */
(hover: none) and (pointer: coarse)
/* iPad Pro */
(hover: none) and (pointer: coarse) and (min-width: 1024px)

Apoi voi combina interogările mele de aspect CSS și interogările mele JavaScript, așa că consider dispozitivul de intrare ca factor principal sprijinite prin lățime, mai degrabă decât invers.

Sfaturi pentru ScrollTrigger

Dacă utilizați GSAP Plugin ScrollTrigger, există un mic utilitar la îndemână pe care îl puteți conecta pentru a discerne cu ușurință capacitățile tactile ale dispozitivului: ScrollTrigger.isTouch.

  • 0 - fără atingere (doar indicatorul/mouse-ul)
  • 1 - numai la atingere dispozitiv (cum ar fi un telefon)
  • 2 – dispozitivul poate accepta atingeţi intrare și cursorul mouse-ului (cum ar fi tabletele Windows)
if (ScrollTrigger.isTouch) {
  // any touch-capable device...
}

// or get more specific: 
if (ScrollTrigger.isTouch === 1) {
  // touch-only device
}

Un alt sfat pentru o animație receptivă declanșată de defilare...

Următoarea demonstrație de mai jos mută o galerie de imagini pe orizontală, dar lățimea se modifică în funcție de dimensiunea ecranului. Dacă redimensionați ecranul când sunteți la jumătatea unei animații curățate, puteți ajunge cu animații rupte și valori învechite. Acesta este o viteză obișnuită, dar care este ușor de rezolvat! Introduceți calculul care depinde de dimensiunea ecranului într-o valoare funcțională și setați invalidateOnRefresh:true. În acest fel, ScrollTrigger va recalcula acea valoare pentru dvs. atunci când browserul se redimensionează.

Sfat tocilar GSAP bonus!

Pe dispozitivele mobile, bara de adrese a browserului se afișează și se ascunde de obicei pe măsură ce derulați. Acesta contează ca un eveniment de redimensionare și va declanșa a ScrollTrigger.refresh(). Acest lucru ar putea să nu fie ideal, deoarece poate provoca salturi în animația dvs. GSAP 3.10 a fost adăugat ignoreMobileResize. Nu afectează modul în care se comportă bara de browser, dar împiedică ScrollTrigger.refresh() de la tragere pentru mici redimensionări verticale pe dispozitivele doar cu atingere.

ScrollTrigger.config({
  ignoreMobileResize: true
});

Principii de mișcare

M-am gândit să vă las câteva bune practici de luat în considerare atunci când lucrați cu mișcare pe web.

Distanta si relaxare

Un lucru mic, dar important, care este ușor de uitat cu animația receptivă, este relația dintre viteză, impuls și distanță! Animație bună ar trebui să imite lumea reală să te simți credibil și durează mai mult timp în lumea reală pentru a parcurge o distanță mai mare. Acordați atenție distanței pe care o parcurge animația dvs. și asigurați-vă că durata și relaxarea utilizate au sens în contextul altor animații.

De asemenea, puteți aplica adesea o relaxare mai dramatică elementelor cu mai multe deplasări pentru a arăta impulsul crescut:

Pentru anumite cazuri de utilizare, poate fi util să ajustați durata mai dinamic în funcție de lățimea ecranului. În următoarea demonstrație pe care o folosim gsap.utils pentru a fixa valoarea pe care o primim înapoi de la curent window.innerWidth într-un interval rezonabil, atunci mapam acel număr la o durată.

Spațiere și cantitate

Un alt lucru de reținut este distanța și cantitatea de elemente la diferite dimensiuni ale ecranului. Citând Steven Shaw:

Dacă aveți un fel de animație ambientală (paralaxă, nori, copaci, confetti, decorațiuni etc.) care sunt distanțate în jurul ferestrei, asigurați-vă că scala și/sau ajustați cantitatea în funcție de dimensiunea ecranului. Ecranele mari au nevoie probabil de mai multe elemente răspândite peste tot, în timp ce ecranele mici au nevoie doar de câteva pentru același efect.

Îmi place cum Opher Vishnia se gândește la animație ca pe o scenă. Adăugarea și eliminarea elementelor nu trebuie să fie doar o formalitate, ci poate face parte din coregrafia generală.

Atunci când proiectați animații responsive, provocarea nu este cum să înghesuiți același conținut în fereastra de vizualizare astfel încât să „se potrivească”, ci mai degrabă cum să organizați setul de conținut existent astfel încât să comunice aceeași intenție. Aceasta înseamnă să alegeți în mod conștient ce piese de conținut să adăugați și pe care să le eliminați. De obicei, în lumea animației, lucrurile nu ies doar în cadru sau ies din cadru. Este logic să ne gândim la elemente ca intrând sau ieșind din „scenă”, animand acea tranziție într-un mod care are sens vizual și tematic.

Și asta e lotul. Dacă aveți mai multe sfaturi de animație receptivă, introduceți-le în secțiunea de comentarii. Dacă este ceva foarte util, le voi adăuga la acest compendiu de informații!

addenda

Încă o notă de la Tom Miller pe măsură ce pregăteam acest articol:

Probabil că am întârziat cu acest sfat pentru articolul dvs. de animații receptive, dar vă recomand cu căldură „finalizați toate animațiile înainte de a construi”. În prezent, modific unele animații de site cu „versiuni mobile”. Slavă Domnului pentru gsap.matchMedia… dar cu siguranță mi-aș fi dorit să știm că vor exista machete/animații mobile separate de la început.

Cred că apreciem cu toții că acest sfat pentru a „planifica dinainte” a venit în ultimul moment. Mulțumesc, Tom, și mult succes cu acele modernizări.

Timestamp-ul:

Mai mult de la CSS Trucuri