CSS Nieskończone suwaki 3D PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. Aj.

CSS Nieskończone suwaki 3D

W tej serii, tworzyliśmy suwaki graficzne wyłącznie za pomocą HTML i CSS. Pomysł polega na tym, że możemy użyć tego samego znacznika, ale innego CSS, aby uzyskać bardzo różne wyniki, bez względu na to, ile wrzucimy obrazów. Zaczęliśmy od okrągłego suwaka, który obraca się w nieskończoność, trochę jak fidget spinner, który przechowuje obrazy. Następnie stworzyliśmy taki, który przegląda stos zdjęć.

Tym razem zanurzamy się w trzeci wymiar. Na początku będzie to wyglądało na trudne, ale większość kodu, któremu się przyglądamy, jest dokładnie tym, czego użyliśmy w pierwszych dwóch artykułach z tej serii, z pewnymi modyfikacjami. Tak więc, jeśli dopiero zaczynasz przygodę z serią, sugerowałbym sprawdzenie innych pod kątem kontekstu pojęć, których tutaj używamy.

Seria suwaków CSS

Oto, do czego dążymy:

Na pierwszy rzut oka wygląda to tak, jakbyśmy mieli obracający się sześcian z czterema obrazami. Ale w rzeczywistości mamy do czynienia w sumie z sześcioma obrazami. Oto suwak z innej perspektywy:

Teraz, gdy mamy już dobry obraz tego, jak rozmieszczone są obrazy, przeanalizujmy kod, aby zobaczyć, jak się tam dostać.

Podstawowa konfiguracja

Ten sam kod HTML, co pozostałe suwaki, których użyliśmy dla innych suwaków:

Po raz kolejny używamy CSS Grid do umieszczania obrazów w stosie, jeden na drugim:

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

Animacja

Logika tego suwaka jest bardzo podobna do okrągły suwak z pierwszego artykułu. W rzeczywistości, jeśli ponownie obejrzysz powyższy film, zobaczysz, że obrazy są umieszczone w sposób, który tworzy wielokąt. Po pełnym obrocie powraca do pierwszego obrazu.

Polegaliśmy na CSS transform-origin i animation-delay właściwości dla tego pierwszego suwaka. Ta sama animacja jest stosowana do wszystkich elementów obrazu, które obracają się wokół tego samego punktu. Następnie, stosując różne opóźnienia, poprawnie umieszczamy wszystkie obrazki wokół dużego koła.

Implementacja będzie nieco inna dla naszego slidera 3D. Za pomocą transform-origin nie zadziała tutaj, ponieważ pracujemy w 3D, więc użyjemy transform zamiast tego poprawnie umieść wszystkie obrazy, a następnie obróć pojemnik.

Ponownie sięgamy po Sass, abyśmy mogli przejrzeć liczbę obrazów i zastosować nasze przekształcenia:

@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 */
  }
}

Być może zastanawiasz się, dlaczego wskakujemy prosto w Sass. Zaczęliśmy od ustalonej liczby obrazów przy użyciu standardowego CSS w innych artykułach, zanim uogólniliśmy kod za pomocą Sass, aby uwzględnić dowolną liczbę (N) obrazów. Cóż, myślę, że teraz rozumiesz, o co chodzi i możemy zrezygnować z całej tej pracy odkrywania, aby przejść do rzeczywistej implementacji.

Połączenia transform właściwość przyjmuje trzy wartości, które zilustrowałem tutaj:

CSS Nieskończone suwaki 3D

Najpierw obracamy wszystkie obrazy jeden nad drugim. Kąt obrotu zależy od liczby obrazów. Do N obrazów, mamy przyrost równy 360deg/N. Wtedy my translate wszystkie obrazy o tę samą wartość w taki sposób, aby ich punkty środkowe spotkały się po bokach.

Przedstawienie stosu obrazów ułożonych płasko w okrąg z czerwoną linią przechodzącą przez środek obrazów.
CSS Nieskończone suwaki 3D

Istnieje pewna nudna geometria, która pomaga wyjaśnić, jak to wszystko działa, ale odległość jest równa 50%/tan(180deg/N). Z podobnym równaniem mieliśmy do czynienia podczas tworzenia okrągłego suwaka ( transform-origin: 50% 50%/sin(180deg/N) ).

Na koniec obracamy obrazy wokół osi x o 90deg aby uzyskać pożądany układ. Oto film, który ilustruje, co robi ostatnia rotacja:

Teraz wystarczy obrócić cały kontener, aby stworzyć nasz nieskończony slider.

.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); }
}

Ten kod może być trudny do zrozumienia, więc cofnijmy się o chwilę i wróćmy do animacji, którą stworzyliśmy dla okrągłego suwaka. Oto, co napisaliśmy w pierwszym artykule:

.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); }
}

Klatki kluczowe są prawie identyczne. Mamy te same wartości procentowe, tę samą pętlę i ten sam obrót.

Dlaczego oba są takie same? Ponieważ ich logika jest taka sama. W obu przypadkach obrazy są ułożone wokół okrągłego kształtu i musimy obrócić całość, aby wyświetlić każdy obraz. W ten sposób mogłem skopiować klatki kluczowe z okrągłego suwaka i użyć tego samego kodu dla naszego suwaka 3D. Jedyna różnica polega na tym, że musimy obrócić pojemnik o -90deg wzdłuż osi X, aby zobaczyć obrazy, ponieważ już je obróciliśmy 90deg na tej samej osi. Następnie dodajemy odrobinę perspective aby uzyskać efekt 3D.

Otóż ​​to! Nasz suwak jest gotowy. Oto ponownie pełne demo. Wszystko, co musisz zrobić, to dodać tyle obrazów, ile chcesz i zaktualizować jedną zmienną, aby wszystko działało.

Pionowy suwak 3D

Skoro gramy w przestrzeni 3D, dlaczego nie zrobić pionowej wersji poprzedniego slidera? Ten ostatni obraca się wzdłuż osi z, ale możemy też poruszać się wzdłuż osi x, jeśli chcemy.

Jeśli porównasz kod dla obu wersji tego suwaka, możesz nie zauważyć różnicy od razu, ponieważ to tylko jeden znak! wymieniłem rotate() w rotateX() wewnątrz klatek kluczowych i obrazu transform. To jest to!

Należy zauważyć, że rotate() odpowiada rotateZ(), więc zmieniając oś z Z do X przesuwamy slider z wersji poziomej na pionową.

Suwak kostki

Nie możemy mówić o 3D w CSS bez mowa o kostkach. I tak, to oznacza, że ​​zrobimy kolejną wersję slidera.

Ideą tej wersji suwaka jest stworzenie rzeczywistego kształtu sześcianu z obrazami i obrócenie całości wokół innej osi. Ponieważ jest to sześcian, mamy do czynienia z sześcioma ścianami. Użyjemy sześciu obrazów, po jednym dla każdej ściany sześcianu. Więc bez Sass, ale z powrotem do waniliowego CSS.

Ta animacja jest trochę przytłaczająca, prawda? Gdzie w ogóle zaczynasz?

Mamy sześć twarzy, więc musimy wykonać co najmniej sześć obrotów, aby każdy obraz otrzymał obrót. Cóż, właściwie potrzebujemy pięciu obrotów — ostatni przywraca nas z powrotem do pierwszej twarzy obrazu. Jeśli weźmiesz kostkę Rubika — lub inny przedmiot w kształcie kostki, na przykład kostkę do gry — i obrócisz ją ręką, będziesz miał dobre pojęcie o tym, co robimy.

.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); }
}

Połączenia transform właściwość zaczyna się od zerowych obrotów, a w każdym stanie dodajemy nowy obrót na określonej osi, aż osiągniemy sześć obrotów. Następnie wracamy do pierwszego obrazu.

Nie zapominajmy o rozmieszczeniu naszych zdjęć. Każdy z nich jest nakładany na powierzchnię sześcianu za pomocą 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); }

Prawdopodobnie myślisz, że za wartościami, których tam używam, kryje się dziwna, złożona logika, prawda? Więc nie. Wszystko, co zrobiłem, to otworzyłem DevTools i bawiłem się różnymi wartościami rotacji dla każdego obrazu, dopóki nie zrobiłem tego dobrze. Może to zabrzmi głupio, ale hej, to działa — zwłaszcza, że ​​mamy stałą liczbę obrazów i nie szukamy czegoś, co obsługuje N obrazy.

W rzeczywistości zapomnij o wartościach, których używam i spróbuj samodzielnie wykonać rozmieszczenie w ramach ćwiczenia. Zacznij od wszystkich obrazów ułożonych jeden na drugim, otwórz DevTools i gotowe! Prawdopodobnie skończysz z innym kodem i to jest całkowicie w porządku. Istnieją różne sposoby umieszczania obrazów.

O co chodzi z przecinkiem w środku var()? Czy to pomyłka?

To nie literówka, więc nie usuwaj! Jeśli go usuniesz, zauważysz, że wpływa to na położenie pierwszego obrazu. Możesz to zobaczyć w moim kodzie, który zdefiniowałem --_t dla wszystkich obrazów z wyjątkiem pierwszego, ponieważ potrzebuję tylko tłumaczenia. Ten przecinek powoduje, że zmienna powraca do wartości null. Bez przecinka nie będziemy mieli powrotu, a cała wartość będzie nieprawidłowa.

Cena Od Specyfikacja:

Uwaga: tzn. var(--a,) jest poprawną funkcją, określającą, że jeśli --a właściwość niestandardowa jest nieprawidłowa lub jej brakuje, plik var()` należy zastąpić niczym.

Losowy suwak kostki

Trochę losowości może być miłym ulepszeniem dla tego rodzaju animacji. Tak więc, zamiast obracać sześcian po kolei, możemy rzucić kostką, że tak powiem, i pozwolić kostce toczyć się tak, jak chce.

Fajne prawda? Nie wiem jak Wam, ale mnie ta wersja bardziej odpowiada! Jest to bardziej interesujące, a przejścia są satysfakcjonujące do oglądania. I zgadnij co? Możesz bawić się wartościami, aby stworzyć własny losowy suwak kostki!

Logika nie jest w rzeczywistości przypadkowa — po prostu tak się wydaje. Ty definiujesz a transform na każdej klatce kluczowej, która pozwala pokazać jedną twarz i… cóż, to naprawdę to! Możesz wybrać dowolne zamówienie.

@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); }
}

Używam rotate3d() tym razem, ale nadal polegam na DevTools, aby znaleźć wartości, które wydają mi się „właściwe”. Nie próbuj szukać związku między klatkami kluczowymi, ponieważ po prostu go nie ma. Definiuję osobne transformacje, a następnie oglądam „losowy” wynik. Upewnij się, że pierwszy obraz jest odpowiednio pierwszą i ostatnią klatką, i pokaż inny obraz na każdej z pozostałych klatek.

Nie jesteś zobowiązany do korzystania z rotate3d() zmienić tak jak ja. Możesz także łączyć różne obroty, tak jak zrobiliśmy to w poprzednim przykładzie. Baw się i zobacz, co możesz wymyślić! Będę czekać, aż podzielisz się ze mną swoją wersją w sekcji komentarzy!

Zamykając

Mam nadzieję, że podobała ci się ta mała seria. Zbudowaliśmy kilka zabawnych (i zabawnych) suwaków, ucząc się przy okazji wielu rodzajów koncepcji CSS — od umieszczania siatki i kolejności układania, po opóźnienia animacji i transformacje. Mogliśmy nawet pobawić się odrobiną Sass, aby przeglądać szereg elementów.

I zrobiliśmy to wszystko z dokładnie tym samym kodem HTML dla każdego stworzonego przez nas slidera. Jakie to jest świetne? CSS jest cholernie potężny i jest w stanie osiągnąć tak wiele bez pomocy JavaScript.

Znak czasu:

Więcej z Sztuczki CSS