Glisoare 3D infinite CSS PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Glisoare 3D infinite CSS

În această serie, am făcut glisoare de imagine cu nimic altceva decât HTML și CSS. Ideea este că putem folosi același marcaj, dar CSS diferit pentru a obține rezultate extrem de diferite, indiferent de câte imagini aruncăm. Am început cu un glisor circular care se rotește la infinit, un fel de spinner care conține imagini. Apoi am făcut unul care răsfoiește un teanc de fotografii.

De data aceasta, ne scufundăm în a treia dimensiune. Va părea greu la început, dar o mare parte din codul la care ne uităm este exact ceea ce am folosit în primele două articole din această serie, cu unele modificări. Deci, dacă abia acum intri în serie, aș sugera să le verifici pe celelalte pentru contextul conceptelor pe care le folosim aici.

Seria CSS Sliders

Acesta este ceea ce ne propunem:

La prima vedere, se pare că avem un cub rotativ cu patru imagini. Dar, în realitate, avem de-a face cu șase imagini în total. Iată cursorul dintr-un unghi diferit:

Acum că avem o imagine bună pentru modul în care sunt aranjate imaginile, să disecăm codul pentru a vedea cum ajungem acolo.

Configurația de bază

Același HTML ca și restul glisoarelor pe care le-am folosit pentru celelalte glisoare:

Și încă o dată, folosim CSS Grid pentru a plasa imaginile într-o stivă, una peste alta:

.gallery {
  display: grid;
}
.gallery > img {
  grid-area: 1 / 1;
  width: 160px;
  aspect-ratio: 1;
  object-fit: cover;
}

Animația

Logica pentru acest glisor este foarte asemănătoare cu cursorul circular din primul articol. De fapt, dacă verificați din nou videoclipul de mai sus, puteți vedea că imaginile sunt plasate într-un mod care creează un poligon. După o rotire completă, se întoarce la prima imagine.

Ne-am bazat pe CSS transform-origin și animation-delay proprietăți pentru primul glisor. Aceeași animație este aplicată tuturor elementelor imaginii, care se rotesc în jurul aceluiași punct. Apoi, folosind diferite întârzieri, plasăm corect toate imaginile în jurul unui cerc mare.

Implementarea va fi puțin diferită pentru glisorul nostru 3D. Folosind transform-origin nu va funcționa aici pentru că lucrăm în 3D, așa că vom folosi transform în schimb să plasați corect toate imaginile, apoi rotiți recipientul.

Căutăm din nou Sass, astfel încât să putem parcurge numărul de imagini și să ne aplicăm transformările:

@for $i from 1 to ($n + 1) {
  .gallery > img:nth-child(#{$i}) {
     transform: 
       rotate(#{360*($i - 1) / $n}deg) /* 1 */
       translateY(50% / math.tan(180deg / $n)) /* 2 */ 
       rotateX(90deg); /* 3 */
  }
}

S-ar putea să vă întrebați de ce sărim direct în Sass. Am început cu un număr fix de imagini folosind vanilla CSS în celelalte articole înainte de a generaliza codul cu Sass pentru a ține cont de orice număr (N) de imagini. Ei bine, cred că ați înțeles ideea acum și putem elimina toată munca de descoperire pentru a ajunge la implementarea reală.

transform proprietatea ia trei valori, pe care le-am ilustrat aici:

Glisoare 3D infinite CSS

Mai întâi rotim toate imaginile una deasupra celeilalte. Unghiul de rotație depinde de numărul de imagini. Pentru N imagini, avem un increment egal cu 360deg/N. Atunci noi translate toate imaginile în aceeași cantitate, astfel încât punctele lor centrale să se întâlnească pe părțile laterale.

Se afișează teancul de imagini aranjate plat într-un cerc cu o linie roșie care trece prin punctul central al imaginilor.
Glisoare 3D infinite CSS

Există o geometrie plictisitoare care ajută la explicarea modului în care funcționează toate acestea, dar distanța este egală cu 50%/tan(180deg/N). Am avut de-a face cu o ecuație similară când am făcut glisorul circular ( transform-origin: 50% 50%/sin(180deg/N) ).

În cele din urmă, rotim imaginile în jurul axei x cu 90deg pentru a obține aranjamentul pe care ni-l dorim. Iată un videoclip care ilustrează ce face ultima rotație:

Acum tot ce trebuie să facem este să rotim întregul container pentru a crea glisorul nostru infinit.

.gallery {
  transform-style: preserve-3d;
  --_t: perspective(280px) rotateX(-90deg);
  animation: r 12s cubic-bezier(.5, -0.2, .5, 1.2) infinite;
}
@keyframes r {
  0%, 3% {transform: var(--_t) rotate(0deg); }
  @for $i from 1 to $n {
    #{($i/$n)*100 - 2}%, 
    #{($i/$n)*100 + 3}% {
      transform: var(--_t) rotate(#{($i / $n) * -360}deg);
    }  
  }
  98%, 100% { transform: var(--_t) rotate(-360deg); }
}

Acest cod ar putea fi greu de înțeles, așa că haideți să facem un pas înapoi și să revedem animația pe care am făcut-o pentru glisorul circular. Iată ce am scris în primul articol:

.gallery {
  animation: m 12s cubic-bezier(.5, -0.2, .5, 1.2) infinite;
}
@keyframes m {
  0%, 3% { transform: rotate(0); }
  @for $i from 1 to $n {
    #{($i / $n) * 100 - 2}%,
    #{($i / $n) * 100 + 3}% { 
      transform: rotate(#{($i / $n) * -360}deg);
    }  
  }
  98%, 100% { transform: rotate(-360deg); }
}

Cadrele cheie sunt aproape identice. Avem aceleași valori procentuale, aceeași buclă și aceeași rotație.

De ce sunt ambele la fel? Pentru că logica lor este aceeași. În ambele cazuri, imaginile sunt aranjate în jurul unei forme circulare și trebuie să rotim totul pentru a afișa fiecare imagine. Așa am putut să copiez cadrele cheie din glisorul circular și să folosesc același cod pentru glisorul nostru 3D. Singura diferență este că trebuie să rotim containerul -90deg de-a lungul axei x pentru a vedea imaginile, deoarece le-am rotit deja 90deg pe aceeași axă. Apoi adăugăm o notă de perspective pentru a obține efectul 3D.

Asta e! Glisorul nostru este gata. Iată din nou demo-ul complet. Tot ce trebuie să faceți este să adăugați câte imagini doriți și să actualizați o variabilă pentru a o pune în funcțiune.

Glisor 3D vertical

Deoarece ne jucăm în spațiul 3D, de ce să nu facem o versiune verticală a glisorului anterior? Ultimul se rotește de-a lungul axei z, dar ne putem deplasa și de-a lungul axei x dacă dorim.

Dacă comparați codul pentru ambele versiuni ale acestui glisor, este posibil să nu observați imediat diferența, deoarece este doar un caracter! am inlocuit rotate() cu rotateX() în interiorul cadrelor cheie și al imaginii transform. Asta e!

Ar trebui remarcat faptul că rotate() este echivalent cu rotateZ(), deci prin schimbarea axei din Z la X transformăm glisorul din varianta orizontală în cea verticală.

Glisor cub

Nu putem vorbi despre 3D în CSS fără vorbind despre cuburi. Și da, asta înseamnă că vom face o altă versiune a glisorului.

Ideea din spatele acestei versiuni a glisorului este de a crea o formă de cub reală cu imaginile și de a roti totul în jurul diferitelor axe. Deoarece este un cub, avem de-a face cu șase fețe. Vom folosi șase imagini, câte una pentru fiecare față a cubului. Deci, nu Sass, dar înapoi la vanilla CSS.

Acea animație este puțin copleșitoare, nu? De unde începi?

Avem șase fețe, așa că trebuie să efectuăm cel puțin șase rotații, astfel încât fiecare imagine să primească o întorsătură. Ei bine, de fapt, avem nevoie de cinci rotații - ultima ne aduce înapoi la prima față a imaginii. Dacă te duci să apuci un cub Rubik - sau un alt obiect în formă de cub, cum ar fi zarurile - și îl rotești cu mâna, vei avea o idee bună despre ceea ce facem.

.gallery {
  --s: 250px; /* the size */

  transform-style: preserve-3d;
  --_p: perspective(calc(2.5*var(--s)));
  animation: r 9s infinite cubic-bezier(.5, -0.5, .5, 1.5);
}

@keyframes r {
  0%, 3%   { transform: var(--_p); }
  14%, 19% { transform: var(--_p) rotateX(90deg); }
  31%, 36% { transform: var(--_p) rotateX(90deg) rotateZ(90deg); }
  47%, 52% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg); }
  64%, 69% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg); }
  81%, 86% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg) rotateZ(90deg); }
  97%, 100%{ transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg) rotateZ(90deg) rotateY(-90deg); }
}

transform proprietatea începe cu zero rotații și, pe fiecare stare, anexăm o nouă rotație pe o axă specifică până când ajungem la șase rotații. Apoi revenim la prima imagine.

Să nu uităm de plasarea imaginilor noastre. Fiecare este aplicat pe o față a cubului folosind transform:

.gallery img {
  grid-area: 1 / 1;
  width: var(--s);
  aspect-ratio: 1;
  object-fit: cover;
  transform: var(--_t,) translateZ(calc(var(--s) / 2));
}
.gallery img:nth-child(2) { --_t: rotateX(-90deg); }
.gallery img:nth-child(3) { --_t: rotateY( 90deg) rotate(-90deg); }
.gallery img:nth-child(4) { --_t: rotateX(180deg) rotate( 90deg); }
.gallery img:nth-child(5) { --_t: rotateX( 90deg) rotate( 90deg); }
.gallery img:nth-child(6) { --_t: rotateY(-90deg); }

Probabil vă gândiți că există o logică ciudată și complexă în spatele valorilor pe care le folosesc acolo, nu? Ei bine, nu. Tot ce am făcut a fost să deschid DevTools și să mă joc cu diferite valori de rotație pentru fiecare imagine până când am înțeles bine. Poate suna stupid, dar, hei, funcționează - mai ales că avem un număr fix de imagini și nu căutăm ceva care să accepte N imagini.

De fapt, uită de valorile pe care le folosesc și încearcă să faci singur plasamentul ca exercițiu. Începeți cu toate imaginile stivuite una peste alta, deschideți DevTools și mergeți! Probabil vei ajunge cu un alt cod și asta e în regulă. Pot exista diferite moduri de a poziționa imaginile.

Care este trucul cu virgula în interiorul var()? Este o greșeală de tipar?

Nu este o greșeală de tipar, așa că nu o eliminați! Dacă îl eliminați, veți observa că afectează plasarea primei imagini. Puteți vedea că în codul meu pe care l-am definit --_t pentru toate imaginile cu excepția primei pentru că am nevoie doar de o traducere pentru el. Această virgulă face ca variabila să cadă înapoi la o valoare nulă. Fără virgulă, nu vom avea o alternativă și întreaga valoare va fi invalidă.

De la caietul de sarcini:

Notă: Adică var(--a,) este o funcție validă, specificând că dacă --a proprietatea personalizată este nevalidă sau lipsește, the var()` ar trebui înlocuit cu nimic.

Glisor cub aleatoriu

Un pic de aleatorie poate fi o îmbunătățire plăcută pentru acest tip de animație. Deci, mai degrabă decât să rotim cubul în ordine secvențială, putem arunca zarurile, ca să spunem așa, și să lăsăm cubul să se rostogolească așa cum vrea.

Cool nu? Nu stiu voi, dar imi place mai mult aceasta versiune! Este mai interesant și tranzițiile sunt satisfăcătoare de urmărit. Si ghici ce? Puteți juca cu valorile pentru a crea propriul cursor de cub aleatoriu!

Logica nu este deloc aleatorie, ci doar așa pare. Tu definești a transform pe fiecare cadru cheie care vă permite să arătați o singură față și... ei bine, asta este cu adevărat! Puteți alege orice comandă doriți.

@keyframes r {
  0%, 3%   { transform: var(--_p) rotate3d( 0, 0, 0,  0deg); }
  14%,19%  { transform: var(--_p) rotate3d(-1, 1, 0,180deg); }
  31%,36%  { transform: var(--_p) rotate3d( 0,-1, 0, 90deg); }
  47%,52%  { transform: var(--_p) rotate3d( 1, 0, 0, 90deg); }
  64%,69%  { transform: var(--_p) rotate3d( 1, 0, 0,-90deg); }
  81%,86%  { transform: var(--_p) rotate3d( 0, 1, 0, 90deg); }
  97%,100% { transform: var(--_p) rotate3d( 0, 0, 0,  0deg); }
}

eu folosesc rotate3d() de data aceasta, dar încă mă bazez pe DevTools pentru a găsi valorile care mi se par „potrivite”. Nu încercați să găsiți o relație între cadrele cheie pentru că pur și simplu nu există. Definesc transformări separate și apoi urmăresc rezultatul „aleatoriu”. Asigurați-vă că prima imagine este primul și, respectiv, ultimul cadre și afișați o imagine diferită pe fiecare dintre celelalte cadre.

Nu sunteți obligat să utilizați a rotate3d() transforma asa cum am facut eu. De asemenea, puteți înlănțui diferite rotații, așa cum am făcut în exemplul anterior. Joacă-te și vezi ce poți găsi! Vă aștept să împărtășiți versiunea dvs. cu mine în secțiunea de comentarii!

La finalul

Sper că v-a plăcut acest mic serial. Am construit niște glisoare distractive (și amuzante), în timp ce învățăm multe despre tot felul de concepte CSS pe parcurs — de la plasarea grilei și ordinea de stivuire, până la întârzierile și transformările animației. Am ajuns chiar să ne jucăm cu o strop de Sass pentru a parcurge o serie de elemente.

Și am făcut totul cu exact același HTML pentru fiecare glisor pe care l-am creat. Cat de tare e asta? CSS este foarte puternic și capabil să realizeze atât de multe fără ajutorul JavaScript.

Timestamp-ul:

Mai mult de la CSS Trucuri