Для цієї четвертої і останньої статті нашого невелика серія про одноелементні завантажувачі, ми збираємося досліджувати 3D візерунки. Під час створення 3D-елемента важко уявити, що лише одного елемента HTML достатньо, щоб імітувати щось на зразок усіх шість граней куба. Але, можливо, ми зможемо піти з чимось більш кубичним...як натомість показуючи лише три передні сторони фігури — це цілком можливо, і це те, що ми збираємося зробити разом.
Серія статей
- Одноелементні навантажувачі: The Spinner
- Завантажувачі одного елемента: точки
- Одноелементні навантажувачі: бруси
- Одноелементні завантажувачі: перехід у 3D — ти тут
Завантажувач розділених кубів
Ось 3D-завантажувач, у якому куб розділений на дві частини, але складається лише з одного елемента:
Кожна половина куба зроблена за допомогою псевдоелемента:
Круто, правда?! Ми можемо використовувати конічний градієнт із CSS clip-path
на елементі ::before
та ::after
pseudos для імітації трьох видимих граней 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)) }
}
Ось ще раз остання демонстрація:
Завантажувач кубів прогресу
Давайте використаємо ту саму техніку для створення тривимірного завантажувача прогресу. Та ще тільки один елемент!
Ми нічого не змінюємо щодо симуляції куба так само, як робили раніше, окрім зміни висоти завантажувача та співвідношення сторін. Анімація, яку ми створюємо, спирається на напрочуд просту техніку, коли ми оновлюємо ширину лівої сторони, а права сторона заповнює простір, що залишився, завдяки flex-grow: 1
.
Перший крок — додати трохи прозорості правій частині за допомогою opacity
:
Це імітує ефект, коли одна сторона куба заповнена, а інша порожня. Потім оновлюємо колір лівої сторони. Для цього ми або оновлюємо три кольори всередині конічного градієнта, або робимо це, додаючи фоновий колір за допомогою background-blend-mode
:
.loader::before { background-color: #CC333F; /* control the color here */ background-blend-mode: multiply;
}
Цей трюк дозволяє нам оновити колір лише один раз. Права частина завантажувача зливається з трьома відтінками білого з конічного градієнта, створюючи три нові відтінки нашого кольору, навіть якщо ми використовуємо лише одне значення кольору. Колірна хитрість!
Давайте анімуємо ширину лівої сторони завантажувача:
Ой, анімація трохи дивна на початку! Помітили, як це починається за межами куба? Це тому, що ми починаємо анімацію в 0%
ширина. Але завдяки clip-path
і від’ємної маржі, яку ми використовуємо, замість цього нам потрібно почати з нашого --_d
змінна, яку ми використовували для визначення clip-path
балів і від’ємної маржі:
@keyframes load { 0%, 5% {width: var(--_d); } 95%, 100% {width: 100%; }
}
Це трохи краще:
Але ми можемо зробити цю анімацію ще більш плавною. Ви помітили, що нам чогось не вистачає? Дозвольте мені показати вам знімок екрана, щоб порівняти, як має виглядати остаточна демонстрація з останньою демонстрацією:
Це нижня грань куба! Оскільки другий елемент прозорий, нам потрібно побачити нижню грань цього прямокутника, як ви можете бачити в лівому прикладі. Це непомітно, але має бути там!
Ми можемо додати градієнт до основного елемента та обрізати його, як ми зробили з псевдо:
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%; }
}
Це воно! Ми щойно використали розумну техніку, яка використовує псевдоелементи, конічні градієнти, відсікання, змішування фону та негативні поля, щоб отримати не один, а два привабливі 3D-завантажувачі з лише одним елементом у розмітці.
Більше 3D
Ми все ще можемо піти далі та змоделювати нескінченну кількість 3D-кубів, використовуючи один елемент — так, це можливо! Ось сітка з кубів:
Ця демонстрація та наступні демонстрації не підтримуються в Safari на момент написання.
Божевільний, правда? Тепер ми створюємо повторюваний візерунок із кубів, виготовлених із використанням одного елемента… і жодних псевдо! Я не буду вдаватися в подробиці математики, яку ми використовуємо (там є дуже конкретні цифри), але ось цифра, щоб уявити, як ми сюди дійшли:
Спочатку ми використовуємо 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-техніка, давайте використаємо її для створення варіацій завантажувача, погравши з різними анімаціями. Наприклад, як щодо повторюваного візерунка з кубиків, які нескінченно ковзають зліва направо?
Цей завантажувач визначає чотири куби в одному ряду. Тобто наш --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;
}
Ось що ми маємо наразі з червоним контуром, щоб показати межі контейнера сітки:
Тепер все, що нам потрібно зробити, це перемістити псевдоелемент праворуч, додавши нашу анімацію:
@keyframes load { to { transform: translate(calc(100% / 4)); }
}
Ви зрозуміли хитрість анімації? Давайте завершимо це, приховавши переповнений візерунок куба і додавши легке маскування, щоб створити той ефект згасання, що початок і кінець:
.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);
}
Ми можемо зробити це набагато гнучкішим, ввівши змінну, --n
, щоб встановити, скільки кубів одночасно відображатиметься в контейнері. А оскільки загальна кількість кубиків у викрійці має бути на один більше ніж --n
, ми можемо виразити це як calc(var(--n) + 1)
.
Ось усе:
Гаразд, ще один схожий 3D-завантажувач, але куби змінюють колір послідовно, а не ковзають:
Ми будемо покладатися на анімований фон 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-завантажувачі, які ми створили разом, а також кілька інших, щоб розкрутити вашу уяву:
Це обгортання
Я справді сподіваюся, що вам сподобалося проводити зі мною час, створюючи завантажувачі окремих елементів протягом останніх кількох тижнів. Це божевілля, що ми почали з, здавалося б, простого спінера, а потім поступово додавали нові елементи, щоб працювати самостійно, аж до 3D-техніки, яка все ще використовує лише один елемент у розмітці. Саме так виглядає CSS, коли ми використовуємо його можливості: масштабований, гнучкий і багаторазовий.
Ще раз дякую, що прочитали цю маленьку серію! Я підпишусь, нагадаю вам, що у мене є колекція понад 500 навантажувачів якщо ви шукаєте більше ідей і натхнення.
Серія статей
- Одноелементні навантажувачі: The Spinner
- Завантажувачі одного елемента: точки
- Одноелементні навантажувачі: бруси
- Одноелементні завантажувачі: перехід у 3D — ти тут
Одноелементні завантажувачі: переходимо до 3D! спочатку опубліковано на CSS-трюки. Ти повинен отримати інформаційний бюлетень.
- "
- 10
- 3d
- 9
- 95%
- a
- МЕНЮ
- доданий
- ВСІ
- дозволяє
- завжди
- Інший
- Застосовувати
- навколо
- стаття
- статті
- фон
- оскільки
- перед тим
- за
- Краще
- між
- Біт
- будувати
- Може отримати
- код
- збір
- поєднання
- комплекс
- Контейнер
- зміст
- контроль
- управління
- створювати
- створення
- деталь
- докладно
- DID
- різний
- дисплей
- відстань
- Dropbox
- кожен
- ефект
- встановити
- і т.д.
- все
- точно
- приклад
- дослідити
- Face
- особи
- знайомий
- Рисунок
- кінець
- Перший
- гнучкий
- після
- від
- перед
- Повний
- далі
- розрив
- буде
- сітка
- має
- висота
- тут
- дуже
- надія
- Як
- HTTPS
- ідея
- ідеї
- уяву
- В інших
- includes
- натхнення
- введення
- IT
- тримати
- шар
- вчений
- Залишати
- трохи
- загрузка
- подивитися
- шукати
- made
- зробити
- Робить
- маска
- математики
- Матриця
- засоби
- більше
- рухатися
- негативний
- номер
- номера
- Інше
- власний
- частина
- Викрійки
- частин
- ігри
- точок
- це можливо
- попередній
- опублікований
- читання
- рекомендувати
- решті
- представляє
- REST
- Safari
- то ж
- масштабовані
- Серія
- комплект
- Форма
- форми
- Поділитись
- Показувати
- підпис
- аналогічний
- простий
- з
- один
- Розмір
- So
- деякі
- що в сім'ї щось
- Простір
- конкретний
- Витрати
- розкол
- площа
- стек
- старт
- почалася
- починається
- Як і раніше
- методи
- Команда
- річ
- три
- час
- разом
- торкатися
- Перетворення
- прозорість
- прозорий
- Оновити
- us
- використання
- значення
- видимий
- Що
- в той час як
- ширше
- слова
- Work
- лист
- вашу