CSS Infinite і Circular Rotating Image Slider PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.

CSS Infinite і Circular Rotating Image Slider

Повзунки зображень (також звані каруселями) є всюди. Існує багато трюків CSS для створення загального слайдера де зображення ковзають зліва направо (або навпаки). Це та сама угода безліч бібліотек JavaScript які створюють химерні повзунки зі складною анімацією. Ми не збираємося робити нічого з цього в цій публікації.

У невеликій серії статей ми збираємося дослідити деякі дивовижні та незвичайні повзунки лише для CSS. Якщо ви втомилися бачити ті самі старі класичні слайдери, тоді ви в потрібному місці!

Серія слайдерів CSS

У цій першій статті ми почнемо з того, що я називаю «повзунок кругового обертового зображення»:

Круто правда? давайте розберемо код!

Розмітка HTML

Якщо ви стежите за моєю серією фантазійні прикраси зображення or Сітка CSS і власні фігури, тоді ви знаєте, що моє перше правило — працювати з найменшим можливим HTML. Я завжди намагаюся знайти рішення CSS, перш ніж захаращувати код великою кількістю

s та інші речі.

Тут діє те саме правило — наш код — це не що інше, як список зображень у контейнері.

Скажімо, ми працюємо з чотирма зображеннями:

Це воно! Тепер перейдемо до цікавої частини коду. Але спочатку ми зануримося в це, щоб зрозуміти логіку роботи нашого слайдера.

Як це працює?

Ось відео де я знімаю overflow: hidden з CSS, щоб ми могли краще зрозуміти, як рухаються зображення:

Наші чотири зображення розташовані на великому колі, яке обертається проти годинникової стрілки.

CSS Infinite і Circular Rotating Image Slider

Усі зображення мають однаковий розмір (позначено S на малюнку). Зверніть увагу на синє коло, яке перетинається з центром усіх зображень і має радіус (R). Це значення знадобиться нам пізніше для нашої анімації. R дорівнює 0.707 * S. (Я збираюся пропустити геометрію, яка дає нам це рівняння.)

Давайте напишемо CSS!

Ми будемо використовувати Сітка CSS щоб розмістити всі зображення в одній області одне над одним:

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

Поки нічого надто складного. Складна частина — це анімація.

Ми говорили про обертання великого кола, але насправді ми будемо обертати кожне зображення окремо, створюючи ілюзію великого обертового кола. Отже, давайте визначимо анімацію, m, і застосуйте його до елементів зображення:

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

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

Основний трюк покладається на цю виділену лінію. За замовчуванням CSS transform-origin властивість дорівнює center (Або 50% 50%), який змушує зображення обертатися навколо свого центру, але нам це не потрібно. Нам потрібно, щоб зображення оберталося навколо центру велике коло який містить наші зображення, отже, нове значення для transform-origin.

Оскільки R дорівнює 0.707 * S, ми можемо це сказати R дорівнює 70.7% від розміру зображення. Ось малюнок, щоб проілюструвати, як ми отримали 120.7% значення:

CSS Infinite і Circular Rotating Image Slider PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.
CSS Infinite і Circular Rotating Image Slider

Давайте запустимо анімацію та подивимось, що станеться:

Я знаю, я знаю. Результат далекий від того, чого ми хочемо, але насправді ми дуже близькі. Може здатися, що там лише одне зображення, але не забувайте, що ми склали всі зображення одне на одне. Усі вони обертаються одночасно, і видно лише верхнє зображення. Нам потрібно затримати анімацію кожного зображення, щоб уникнути цього накладання.

.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 */

Справи вже йдуть на краще!

Якщо ми приховаємо переповнення на контейнері, ми вже побачимо повзунок, але ми трохи оновимо анімацію, щоб кожне зображення залишалося видимим протягом короткого періоду, перш ніж воно переміститься.

Ми збираємося оновити наші ключові кадри анімації, щоб зробити саме це:

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

Для кожного 90deg (360deg/4, Де 4 кількість зображень) додамо невелику паузу. Кожне зображення залишатиметься видимим для 5% загальної тривалості, перш ніж перейти до наступного (27%-22%, 52%-47%тощо). Я збираюся оновити animation-timing-function використання cubic-bezier() функція, щоб зробити анімацію трохи привабливішою:

Тепер наш слайдер ідеальний! Ну, майже ідеально, тому що нам все ще бракує останнього штриха: кольорової круглої рамки, яка обертається навколо наших зображень. Ми можемо використовувати псевдоелемент на .gallery обгортка, щоб це зробити:

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

Я створив коло з a повторюваний конічний градієнт для фону під час використання a трюк маскування що показує лише доповнену область. Потім я застосовую до нього ту саму анімацію, яку ми визначили для зображень.

Ми готові! У нас є крутий круглий слайдер:

Давайте додамо більше зображень

Працювати з чотирма зображеннями добре, але було б краще, якби ми могли масштабувати його до будь-якої кількості зображень. Зрештою, це призначення повзунка зображення. Ми повинні мати можливість розглянути N зображення.

Для цього ми збираємося зробити код більш загальним, представивши Sass. Спочатку ми визначаємо змінну для кількості зображень ($n), і ми оновимо кожну частину, де ми жорстко закодували кількість зображень (4).

Почнемо із затримок:

.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 */

Формула затримки така (1 - $i)*duration/$n, що дає нам такий цикл Sass:

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

Ми також можемо зробити тривалість змінною, якщо дійсно хочемо. Але давайте перейдемо до анімації:

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

Давайте спростимо це, щоб краще бачити візерунок:

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

Крок між кожним станом дорівнює 25% - який є 100%/4 — і додаємо а -90deg кут — який є -360deg/4. Це означає, що ми можемо написати наш цикл так:

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

Оскільки кожен образ займає 5% анімації, ми змінюємо це:

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

…з цим:

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

Слід зазначити, що 5% це довільне значення, яке я вибираю для цього прикладу. Ми також можемо зробити це змінною, щоб контролювати, скільки часу кожне зображення має залишатися видимим. Я збираюся пропустити це заради простоти, але для домашнього завдання ви можете спробувати це зробити та поділитися своєю реалізацією в коментарях!

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

Останнім кроком є ​​оновлення transform-origin. Нам знадобляться деякі геометричні трюки. Якою б не була кількість зображень, конфігурація завжди однакова. У нас є зображення (маленькі кола) у великому колі, і нам потрібно знайти значення радіуса, R.

CSS Infinite і Circular Rotating Image Slider PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.
CSS Infinite і Circular Rotating Image Slider

Можливо, вам не потрібне нудне пояснення геометрії, тому ось як ми це знайдемо R:

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

Якщо ми виразимо це у відсотках, це дасть нам:

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

…що означає transform-origin значення дорівнює:

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

Були зроблені! У нас є слайдер, який працює з будь-якими номерами зображень!

Давайте розмістимо дев’ять зображень:

Додайте скільки завгодно зображень і оновіть $n змінна із загальною кількістю зображень.

Підводячи підсумок

За допомогою кількох хитрощів із використанням перетворень CSS і стандартної геометрії ми створили гарний круглий повзунок, який не потребує багато коду. Що цікаво в цьому слайдері, так це те, що нам не потрібно копіювати зображення, щоб зберегти нескінченну анімацію, оскільки у нас є коло. Після повного обертання ми повернемося до першого зображення!

Часова мітка:

Більше від CSS-хитрощі