CSS Nieskończony i okrągły obrotowy suwak obrazu PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Nieskończony i okrągły obrotowy suwak obrazu CSS

Suwaki obrazu (zwane także karuzelami) są wszędzie. Są wiele sztuczek CSS, aby stworzyć wspólny suwak gdzie obrazy przesuwają się od lewej do prawej (lub odwrotnie). To samo dotyczy wiele dostępnych bibliotek JavaScript które tworzą fantazyjne suwaki ze złożonymi animacjami. W tym poście nie będziemy tego robić.

W krótkiej serii artykułów przyjrzymy się niektórym fantazyjnym i niezwykłym suwakom obsługującym tylko CSS. Jeśli jesteś zmęczony oglądaniem tych samych starych klasycznych suwaków, to jesteś we właściwym miejscu!

Seria suwaków CSS

W tym pierwszym artykule zaczniemy od czegoś, co nazywam „okrągłym obracającym się suwakiem obrazu”:

Fajne prawda? przeanalizujmy kod!

Znacznik HTML

Jeśli śledziłeś moją serię z fantazyjne dekoracje obrazu or Siatka CSS i niestandardowe kształty, to wiesz, że moją pierwszą zasadą jest praca z jak najmniejszym kodem HTML. Zawsze staram się znaleźć rozwiązania CSS, zanim zaśmiecę mój kod dużą ilością

s i inne rzeczy.

Tutaj obowiązuje ta sama zasada — nasz kod to nic innego jak lista obrazków w kontenerze.

Powiedzmy, że pracujemy z czterema obrazami:

Otóż ​​to! Przejdźmy teraz do interesującej części kodu. Ale najpierw zagłębimy się w to, aby zrozumieć logikę działania naszego suwaka.

Jak to działa?

Oto film, w którym usuwam overflow: hidden z CSS, abyśmy mogli lepiej zrozumieć, w jaki sposób obrazy się poruszają:

To tak, jakby nasze cztery obrazy były umieszczone na dużym kole, które obraca się w kierunku przeciwnym do ruchu wskazówek zegara.

Nieskończony i okrągły obrotowy suwak obrazu CSS

Wszystkie obrazy mają ten sam rozmiar (oznaczony przez S Na rysunku). Zwróć uwagę na niebieskie kółko, które przecina się ze środkiem wszystkich obrazów i ma promień (R). Będziemy potrzebować tej wartości później dla naszej animacji. R jest równe 0.707 * S. (Pominę geometrię, która daje nam to równanie).

Napiszmy trochę CSS!

Będziemy używać Siatka CSS aby umieścić wszystkie obrazy w tym samym obszarze jeden nad drugim:

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

  display: grid;
  width: var(--s);
  aspect-ratio: 1;
  padding: calc(var(--s) / 20); /* we will see the utility of this later */
  border-radius: 50%;
}
.gallery > img {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}

Na razie nic skomplikowanego. Trudną częścią jest animacja.

Mówiliśmy o obracaniu dużego koła, ale w rzeczywistości będziemy obracać każdy obraz indywidualnie, tworząc iluzję dużego obracającego się koła. Zdefiniujmy więc animację, mi zastosuj go do elementów obrazu:

.gallery > img {
  /* same as before */
  animation: m 8s infinite linear;
  transform-origin: 50% 120.7%;
}

@keyframes m {
  100% { transform: rotate(-360deg); }
}

Główna sztuczka opiera się na tej podświetlonej linii. Domyślnie plik CSS transform-origin właściwość jest równa center (lub 50% 50%), co sprawia, że ​​obraz obraca się wokół środka, ale nie jest nam do tego potrzebny. Potrzebujemy, aby obraz obracał się wokół środka duże koło który zawiera nasze obrazy, stąd nowa wartość for transform-origin.

Ponieważ R jest równe 0.707 * S, możemy to powiedzieć R jest równe 70.7% od rozmiaru obrazu. Oto rysunek ilustrujący, w jaki sposób otrzymaliśmy 120.7% wartość:

CSS Nieskończony i okrągły obrotowy suwak obrazu PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.
Nieskończony i okrągły obrotowy suwak obrazu CSS

Uruchommy animację i zobaczmy, co się stanie:

Wiem wiem. Rezultat jest daleki od tego, czego chcemy, ale w rzeczywistości jesteśmy bardzo blisko. Może się wydawać, że jest tam tylko jeden obraz, ale nie zapominaj, że ułożyliśmy wszystkie obrazy jeden na drugim. Wszystkie obracają się w tym samym czasie i widoczny jest tylko górny obraz. Potrzebujemy opóźnienia animacji każdego obrazu, aby uniknąć tego nakładania się.

.gallery > img:nth-child(2) { animation-delay: -2s; } /* -1 * 8s / 4 */
.gallery > img:nth-child(3) { animation-delay: -4s; } /* -2 * 8s / 4 */
.gallery > img:nth-child(4) { animation-delay: -6s; } /* -3 * 8s / 4 */

Sytuacja już się poprawia!

Jeśli ukryjemy przepełnienie na kontenerze, możemy już zobaczyć suwak, ale zaktualizujemy trochę animację, aby każdy obraz był widoczny przez krótki czas, zanim się przesunie.

W tym celu zaktualizujemy nasze klatki kluczowe animacji:

@keyframes m {
  0%, 3% { transform: rotate(0); }
  22%, 27% { transform: rotate(-90deg); }
  47%, 52% { transform: rotate(-180deg); }
  72%, 77% { transform: rotate(-270deg); }
  98%, 100% { transform: rotate(-360deg); }
}

Dla każdego 90deg (360deg/4, Gdzie 4 to liczba obrazów) dodamy małą pauzę. Każdy obraz pozostanie widoczny przez 5% całkowitego czasu trwania, zanim przejdziemy do następnego (27%-22%, 52%-47%itp.). Idę zaktualizować animation-timing-function przy cubic-bezier() funkcja, aby animacja była nieco bardziej wyszukana:

Teraz nasz slider jest idealny! Cóż, prawie idealnie, ponieważ wciąż brakuje nam ostatniego szlifu: kolorowej okrągłej ramki, która obraca się wokół naszych zdjęć. Możemy użyć pseudoelementu na .gallery opakowanie, aby to zrobić:

.gallery {
  padding: calc(var(--s) / 20); /* the padding is needed here */
  position: relative;
}
.gallery::after {
  content: "";
  position: absolute;
  inset: 0;
  padding: inherit; /* Inherits the same padding */
  border-radius: 50%;
  background: repeating-conic-gradient(#789048 0 30deg, #DFBA69 0 60deg);
  mask: 
    linear-gradient(#fff 0 0) content-box, 
    linear-gradient(#fff 0 0);
  mask-composite: exclude;
}
.gallery::after,
.gallery >img {
  animation: m 8s infinite cubic-bezier(.5, -0.2, .5, 1.2);
}

Stworzyłem krąg z a powtarzający się gradient stożkowy dla tła podczas używania a sztuczka maskująca który pokazuje tylko wyściełany obszar. Następnie stosuję do niego tę samą animację, którą zdefiniowaliśmy dla obrazów.

Skończyliśmy! Mamy fajny okrągły suwak:

Dodajmy więcej zdjęć

Praca z czterema obrazami jest dobra, ale byłoby lepiej, gdybyśmy mogli przeskalować ją do dowolnej liczby obrazów. W końcu taki jest cel suwaka obrazu. Powinniśmy umieć się zastanowić N obrazy.

W tym celu uczynimy kod bardziej ogólnym, wprowadzając Sass. Najpierw definiujemy zmienną dla liczby obrazów ($n) i zaktualizujemy każdą część, w której zakodowaliśmy na stałe liczbę obrazów (4).

Zacznijmy od opóźnień:

.gallery > img:nth-child(2) { animation-delay: -2s; } /* -1 * 8s / 4 */
.gallery > img:nth-child(3) { animation-delay: -4s; } /* -2 * 8s / 4 */
.gallery > img:nth-child(4) { animation-delay: -6s; } /* -3 * 8s / 4 */

Wzór na opóźnienie to (1 - $i)*duration/$n, co daje nam następującą pętlę Sass:

@for $i from 2 to ($n + 1) {
  .gallery > img:nth-child(#{$i}) {
    animation-delay: calc(#{(1 - $i) / $n} * 8s);
  }
}

Możemy również uczynić czas trwania zmienną, jeśli naprawdę chcemy. Ale przejdźmy do animacji:

@keyframes m {
  0%, 3% { transform: rotate(0); }
  22%, 27% { transform: rotate(-90deg); }
  47%, 52% { transform: rotate(-180deg); }
  72%, 77% { transform: rotate(-270deg); }
  98%, 100% {transform: rotate(-360deg); }
}

Uprośćmy to, aby uzyskać lepszy widok na wzór:

@keyframes m {
  0% { transform: rotate(0); }
  25% { transform: rotate(-90deg); }
  50% { transform: rotate(-180deg); }
  75% { transform: rotate(-270deg); }
  100% { transform: rotate(-360deg); }
}

Krok między każdym stanem jest równy 25% - który jest 100%/4 — i dodajemy a -90deg kąt - czyli -360deg/4. Oznacza to, że zamiast tego możemy napisać naszą pętlę w ten sposób:

@keyframes m {
  0% { transform: rotate(0); }
  @for $i from 1 to $n {
    #{($i / $n) * 100}% { transform: rotate(#{($i / $n) * -360}deg); }  
  }
  100% { transform: rotate(-360deg); }
}

Ponieważ każdy obraz trwa 5% animacji zmieniamy to:

#{($i / $n) * 100}%

…z tym:

#{($i / $n) * 100 - 2}%, #{($i / $n) * 100 + 3}%

Należy zauważyć, że 5% jest dowolną wartością, którą wybrałem dla tego przykładu. Możemy również ustawić ją jako zmienną kontrolującą, przez jaki czas każdy obraz powinien być widoczny. Pominę to dla uproszczenia, ale w ramach pracy domowej możesz spróbować to zrobić i podzielić się swoją implementacją w komentarzach!

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

Ostatnim elementem jest aktualizacja transform-origin. Będziemy potrzebować kilku sztuczek z geometrią. Bez względu na liczbę obrazów konfiguracja jest zawsze taka sama. Mamy nasze obrazy (małe kółka) umieszczone wewnątrz dużego koła i musimy znaleźć wartość promienia, R.

CSS Nieskończony i okrągły obrotowy suwak obrazu PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.
Nieskończony i okrągły obrotowy suwak obrazu CSS

Prawdopodobnie nie chcesz nudnego wyjaśnienia geometrii, więc oto jak to znaleźć R:

R = S / (2 * sin(180deg / N))

Jeśli wyrazimy to w procentach, otrzymamy:

R = 100% / (2 * sin(180deg / N)) = 50% / sin(180deg / N)

…co oznacza transform-origin wartość jest równa:

transform-origin: 50% (50% / math.sin(180deg / $n) + 50%);

Skończyliśmy! Mamy suwak, który działa z dowolną liczbą obrazów!

Wrzućmy tam dziewięć obrazów:

Dodaj tyle obrazów, ile chcesz i zaktualizuj $n zmienna z całkowitą liczbą obrazów.

Zamykając

Za pomocą kilku sztuczek wykorzystujących transformacje CSS i standardową geometrię stworzyliśmy ładny okrągły suwak, który nie wymaga dużej ilości kodu. Fajne w tym suwaku jest to, że nie musimy zawracać sobie głowy powielaniem obrazów, aby zachować nieskończoną animację, ponieważ mamy okrąg. Po pełnym obrocie wrócimy do pierwszego obrazu!

Znak czasu:

Więcej z Sztuczki CSS