Одноелементні завантажувачі: переходимо до 3D! PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.

Одноелементні завантажувачі: переходимо до 3D!

Для цієї четвертої і останньої статті нашого невелика серія про одноелементні завантажувачі, ми збираємося досліджувати 3D візерунки. Під час створення 3D-елемента важко уявити, що лише одного елемента HTML достатньо, щоб імітувати щось на зразок усіх шість граней куба. Але, можливо, ми зможемо піти з чимось більш кубичним...як натомість показуючи лише три передні сторони фігури — це цілком можливо, і це те, що ми збираємося зробити разом.

Завантажувач розділених кубів

Ось 3D-завантажувач, у якому куб розділений на дві частини, але складається лише з одного елемента:

Запасний варіант для вбудовування CodePen

Кожна половина куба зроблена за допомогою псевдоелемента:

Одноелементні завантажувачі: переходимо до 3D! PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.
Одноелементні завантажувачі: переходимо до 3D!

Круто, правда?! Ми можемо використовувати конічний градієнт із CSS clip-path на елементі ::before та ::after pseudos для імітації трьох видимих ​​граней 3D-куба. Від’ємний запас – це те, що зближує два псевдо, щоб вони перекривалися та імітували повний куб. Решта нашої роботи здебільшого полягає в анімації цих двох половин, щоб отримати акуратні завантажувачі!

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

Одноелементні завантажувачі: переходимо до 3D! PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.
Одноелементні завантажувачі: переходимо до 3D!

У нас є свої змінні та рівняння, тож давайте запустимо їх. Спочатку ми встановимо наші змінні та встановимо розміри для основних .loader Елемент:

.loader { --s: 150px; /* control the size */ --_d: calc(0.353 * var(--s)); /* 0.353 = sin(45deg)/2 */ width: calc(var(--s) + var(--_d)); aspect-ratio: 1; display: flex;
}

Поки що нічого надто божевільного. Ми маємо 150px квадрат, створений як гнучкий контейнер. Тепер ми встановлюємо наші псевдо:

.loader::before,
.loader::after { content: ""; flex: 1;
}

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

.loader::before,
.loader::after { content: ""; flex: 1; background: conic-gradient(from -90deg at calc(100% - var(--_d)) var(--_d), #fff 135deg, #666 0 270deg, #aaa 0);
}

Градієнт є, але це виглядає дивно. Ми потребуємо прикріпіть його до елемента:

.loader::before,
.loader::after { content: ""; flex: 1; background: conic-gradient(from -90deg at calc(100% - var(--_d)) var(--_d), #fff 135deg, #666 0 270deg, #aaa 0); clip-path: polygon(var(--_d) 0, 100% 0, 100% calc(100% - var(--_d)), calc(100% - var(--_d)) 100%, 0 100%, 0 var(--_d));
}

Давайте переконаємося, що дві половини перекривають a негативна маржа:

.loader::before { margin-right: calc(var(--_d) / -2);
} .loader::after { margin-left: calc(var(--_d) / -2);
}

Тепер давайте змусимо їх рухатися!

.loader::before,
.loader::after { /* same as before */ animation: load 1.5s infinite cubic-bezier(0, .5, .5, 1.8) alternate;
} .loader::after { /* same as before */ animation-delay: -.75s
} @keyframes load{ 0%, 40% { transform: translateY(calc(var(--s) / -4)) } 60%, 100% { transform: translateY(calc(var(--s) / 4)) }
}

Ось ще раз остання демонстрація:

Запасний варіант для вбудовування CodePen

Завантажувач кубів прогресу

Давайте використаємо ту саму техніку для створення тривимірного завантажувача прогресу. Та ще тільки один елемент!

Запасний варіант для вбудовування CodePen

Ми нічого не змінюємо щодо симуляції куба так само, як робили раніше, окрім зміни висоти завантажувача та співвідношення сторін. Анімація, яку ми створюємо, спирається на напрочуд просту техніку, коли ми оновлюємо ширину лівої сторони, а права сторона заповнює простір, що залишився, завдяки flex-grow: 1.

Перший крок — додати трохи прозорості правій частині за допомогою opacity:

Запасний варіант для вбудовування CodePen

Це імітує ефект, коли одна сторона куба заповнена, а інша порожня. Потім оновлюємо колір лівої сторони. Для цього ми або оновлюємо три кольори всередині конічного градієнта, або робимо це, додаючи фоновий колір за допомогою background-blend-mode:

.loader::before { background-color: #CC333F; /* control the color here */ background-blend-mode: multiply;
}

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

Запасний варіант для вбудовування CodePen

Давайте анімуємо ширину лівої сторони завантажувача:

Запасний варіант для вбудовування CodePen

Ой, анімація трохи дивна на початку! Помітили, як це починається за межами куба? Це тому, що ми починаємо анімацію в 0% ширина. Але завдяки clip-path і від’ємної маржі, яку ми використовуємо, замість цього нам потрібно почати з нашого --_d змінна, яку ми використовували для визначення clip-path балів і від’ємної маржі:

@keyframes load { 0%, 5% {width: var(--_d); } 95%, 100% {width: 100%; }
}

Це трохи краще:

Запасний варіант для вбудовування CodePen

Але ми можемо зробити цю анімацію ще більш плавною. Ви помітили, що нам чогось не вистачає? Дозвольте мені показати вам знімок екрана, щоб порівняти, як має виглядати остаточна демонстрація з останньою демонстрацією:

Одноелементні завантажувачі: переходимо до 3D! PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.

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

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

background: linear-gradient(#fff1 0 0) bottom / 100% var(--_d) no-repeat;

Ось повний код, коли все зібрано разом:

.loader { --s: 100px; /* control the size */ --_d: calc(0.353*var(--s)); /* 0.353 = sin(45deg) / 2 */ height: var(--s); aspect-ratio: 3; display: flex; background: linear-gradient(#fff1 0 0) bottom / 100% var(--_d) no-repeat; clip-path: polygon(var(--_d) 0, 100% 0, 100% calc(100% - var(--_d)), calc(100% - var(--_d)) 100%, 0 100%, 0 var(--_d));
}
.loader::before,
.loader::after { content: ""; clip-path: inherit; background: conic-gradient(from -90deg at calc(100% - var(--_d)) var(--_d), #fff 135deg, #666 0 270deg, #aaa 0);
}
.loader::before { background-color: #CC333F; /* control the color here */ background-blend-mode: multiply; margin-right: calc(var(--_d) / -2); animation: load 2.5s infinite linear;
}
.loader:after { flex: 1; margin-left: calc(var(--_d) / -2); opacity: 0.4;
} @keyframes load { 0%, 5% { width: var(--_d); } 95%, 100% { width: 100%; }
}
Запасний варіант для вбудовування CodePen

Це воно! Ми щойно використали розумну техніку, яка використовує псевдоелементи, конічні градієнти, відсікання, змішування фону та негативні поля, щоб отримати не один, а два привабливі 3D-завантажувачі з лише одним елементом у розмітці.

Більше 3D

Ми все ще можемо піти далі та змоделювати нескінченну кількість 3D-кубів, використовуючи один елемент — так, це можливо! Ось сітка з кубів:

Запасний варіант для вбудовування CodePen

Ця демонстрація та наступні демонстрації не підтримуються в Safari на момент написання.

Божевільний, правда? Тепер ми створюємо повторюваний візерунок із кубів, виготовлених із використанням одного елемента… і жодних псевдо! Я не буду вдаватися в подробиці математики, яку ми використовуємо (там є дуже конкретні цифри), але ось цифра, щоб уявити, як ми сюди дійшли:

Одноелементні завантажувачі: переходимо до 3D! PlatoBlockchain Data Intelligence. Вертикальний пошук. Ai.
Одноелементні завантажувачі: переходимо до 3D!

Спочатку ми використовуємо a conic-gradient щоб створити повторюваний візерунок куба. Повторення візерунка контролюється трьома змінними:

  • --size: відповідно до назви, це контролює розмір кожного куба.
  • --m: це кількість стовпців.
  • --n: це кількість рядків.
  • --gap: це проміжок або відстань між кубами
.cube { --size: 40px; --m: 4; --n: 5; --gap :10px; aspect-ratio: var(--m) / var(--n); width: calc(var(--m) * (1.353 * var(--size) + var(--gap))); background: conic-gradient(from -90deg at var(--size) calc(0.353 * var(--size)), #249FAB 135deg, #81C5A3 0 270deg, #26609D 0) /* update the colors here */ 0 0 / calc(100% / var(--m)) calc(100% / var(--n));
}

Потім ми накладаємо шар маски, використовуючи інший візерунок такого ж розміру. Це найскладніша частина цієї ідеї. Використовуючи комбінацію a linear-gradient і conic-gradient ми виріжемо кілька частин нашого елемента, щоб залишити видимими лише форми куба.

.cube { /* etc. */ mask: linear-gradient(to bottom right, #0000 calc(0.25 * var(--size)), #000 0 calc(100% - calc(0.25 * var(--size)) - 1.414 * var(--gap)), #0000 0), conic-gradient(from -90deg at right var(--gap) bottom var(--gap), #000 90deg, #0000 0); mask-size: calc(100% / var(--m)) calc(100% / var(--n)); mask-composite: intersect;
}

Код може виглядати дещо складним, але завдяки змінним CSS все, що нам потрібно зробити, це оновити кілька значень, щоб контролювати нашу матрицю кубів. Потрібна сітка 10⨉10? Оновити --m та --n змінні до 10. Потрібен більший проміжок між кубиками? Оновити --gap значення. Значення кольорів використовуються лише один раз, тому оновіть їх для нової палітри кольорів!

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

Запасний варіант для вбудовування CodePen

Цей завантажувач визначає чотири куби в одному ряду. Тобто наш --n значення є 4 та --m дорівнює 1 . Іншими словами, вони нам більше не потрібні!

Натомість ми можемо працювати з --size та --gap змінні в контейнері сітки:

.loader { --size: 70px; --gap: 15px; width: calc(3 * (1.353 * var(--size) + var(--gap))); display: grid; aspect-ratio: 3;
}

Це наш контейнер. У нас є чотири кубики, але ми хочемо показувати лише три в контейнері одночасно, щоб у нас завжди був один, що ковзає, коли інший висувається. Ось чому ми розраховуємо ширину на 3 і встановіть співвідношення сторін 3 а.

Давайте переконаємося, що наш шаблон куба налаштований на ширину чотирьох кубів. Ми зробимо це на контейнері ::before псевдоелемент:

.loader::before { content: ""; width: calc(4 * 100% / 3); /* Code to create four cubes */
}

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

.loader { /* same as before */ justify-content: end;
}

Ось що ми маємо наразі з червоним контуром, щоб показати межі контейнера сітки:

Запасний варіант для вбудовування CodePen

Тепер все, що нам потрібно зробити, це перемістити псевдоелемент праворуч, додавши нашу анімацію:

@keyframes load { to { transform: translate(calc(100% / 4)); }
}
Запасний варіант для вбудовування CodePen

Ви зрозуміли хитрість анімації? Давайте завершимо це, приховавши переповнений візерунок куба і додавши легке маскування, щоб створити той ефект згасання, що початок і кінець:

.loader { --size: 70px; --gap: 15px; width: calc(3*(1.353*var(--s) + var(--g))); display: grid; justify-items: end; aspect-ratio: 3; overflow: hidden; mask: linear-gradient(90deg, #0000, #000 30px calc(100% - 30px), #0000);
}
Запасний варіант для вбудовування CodePen

Ми можемо зробити це набагато гнучкішим, ввівши змінну, --n, щоб встановити, скільки кубів одночасно відображатиметься в контейнері. А оскільки загальна кількість кубиків у викрійці має бути на один більше ніж --n, ми можемо виразити це як calc(var(--n) + 1).

Ось усе:

Запасний варіант для вбудовування CodePen

Гаразд, ще один схожий 3D-завантажувач, але куби змінюють колір послідовно, а не ковзають:

Запасний варіант для вбудовування CodePen

Ми будемо покладатися на анімований фон background-blend-mode для цього:

.loader { /* ... */ background: linear-gradient(#ff1818 0 0) 0% / calc(100% / 3) 100% no-repeat, /* ... */; background-blend-mode: multiply; /* ... */ animation: load steps(3) 1.5s infinite;
}
@keyframes load { to { background-position: 150%; }
}

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

Звідти він анімує фоновий градієнт background-position як триетапну анімацію, щоб кубики блимали кольорами по черзі.

Якщо ви не знайомі зі значеннями, які я використовую для background-position і фоновий синтаксис, я настійно рекомендую одна з моїх попередніх статей і один з мої відповіді Stack Overflow. Там ви знайдете дуже докладне пояснення.

Чи можемо ми оновити кількість кубів, щоб зробити її змінною?

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

Безліч варіацій!

Як і в інших трьох статтях цієї серії, я хотів би дати вам трохи натхнення для створення власних завантажувачів. Ось колекція, яка включає 3D-завантажувачі, які ми створили разом, а також кілька інших, щоб розкрутити вашу уяву:

Запасний варіант для вбудовування CodePen

Це обгортання

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

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


Одноелементні завантажувачі: переходимо до 3D! спочатку опубліковано на CSS-трюки. Ти повинен отримати інформаційний бюлетень.

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

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