W tym czwartym i ostatnim artykule naszego mała seria na ładowarkach jednoelementowych, zamierzamy zbadać wzory 3D. Tworząc element 3D, trudno sobie wyobrazić, że wystarczy jeden element HTML, aby zasymulować coś w rodzaju wszystkich sześciu ścian sześcianu. Ale może ujdzie nam na sucho coś więcej sześcianu-lubić zamiast tego pokazując tylko trzy przednie boki kształtu — jest to całkowicie możliwe i to właśnie zamierzamy zrobić razem.
Seria artykułów
- Ładowarki jednoelementowe: Spinner
- Ładowarki jednoelementowe: Dots
- Ładowarki jednoelementowe: Bary
- Ładowarki jednoelementowe: w 3D — jesteś tutaj
Dzielona ładowarka kostek
Oto program ładujący 3D, w którym sześcian jest podzielony na dwie części, ale składa się tylko z jednego elementu:
Każda połowa sześcianu jest wykonana z pseudoelementu:
Fajnie, prawda?! Możemy użyć gradientu stożkowego z CSS clip-path
na element ::before
i ::after
pseudos do symulacji trzech widocznych ścian sześcianu 3D. Margines ujemny jest tym, co łączy te dwie pseudonimy, aby nachodziły na siebie i symulowały pełny sześcian. Reszta naszej pracy to głównie animowanie tych dwóch połówek, aby uzyskać ładnie wyglądające ładowarki!
Spójrzmy na wizualizację, która wyjaśnia matematykę za punktami ścieżki przycinania użytymi do stworzenia tego elementu przypominającego sześcian:
Mamy nasze zmienne i równanie, więc wykorzystajmy je. Najpierw ustalimy nasze zmienne i ustawimy rozmiar dla głównego .loader
element:
.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;
}
Jak dotąd nic szalonego. Mamy 150px
kwadrat, który jest skonfigurowany jako elastyczny pojemnik. Teraz ustalamy nasze pseudonimy:
.loader::before,
.loader::after { content: ""; flex: 1;
}
To są dwie połówki w .loader
pojemnik. Musimy je pomalować, więc tam nasz gradient stożkowy kopie w:
.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);
}
Gradient jest, ale to wygląda dziwnie. Musimy przypnij go do elementu:
.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));
}
Upewnijmy się, że dwie połówki nakładają się na ujemna marża:
.loader::before { margin-right: calc(var(--_d) / -2);
} .loader::after { margin-left: calc(var(--_d) / -2);
}
Teraz zróbmy ich ruch!
.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)) }
}
Oto ostatnie demo jeszcze raz:
Moduł ładujący kostkę postępu
Użyjmy tej samej techniki, aby stworzyć program ładujący postępy 3D. Tak, wciąż tylko jeden element!
Nie zmieniamy niczego, jeśli chodzi o symulację kostki w taki sam sposób, jak robiliśmy to wcześniej, poza zmianą wysokości i proporcji modułu ładującego. Animacja, którą tworzymy, opiera się na zaskakująco łatwej technice, w której aktualizujemy szerokość lewej strony, podczas gdy prawa strona wypełnia pozostałą przestrzeń, dzięki flex-grow: 1
.
Pierwszym krokiem jest dodanie przezroczystości po prawej stronie za pomocą opacity
:
To symuluje efekt, że jedna strona sześcianu jest wypełniona, podczas gdy druga jest pusta. Następnie aktualizujemy kolor lewej strony. Aby to zrobić, albo aktualizujemy trzy kolory wewnątrz gradientu stożkowego, albo robimy to, dodając kolor tła za pomocą background-blend-mode
:
.loader::before { background-color: #CC333F; /* control the color here */ background-blend-mode: multiply;
}
Ta sztuczka pozwala nam tylko raz zaktualizować kolor. Prawa strona modułu ładującego łączy się z trzema odcieniami bieli z gradientu stożkowego, tworząc trzy nowe odcienie naszego koloru, mimo że używamy tylko jednej wartości koloru. Kolorowa sztuczka!
Animujmy szerokość lewej strony ładowarki:
Ups, animacja jest trochę dziwna na początku! Zauważ, jak to się zaczyna poza sześcianem? Dzieje się tak, ponieważ animację zaczynamy od 0%
szerokość. Ale ze względu na clip-path
i ujemnej marży, którą stosujemy, musimy zamiast tego zacząć od naszego --_d
zmienna, której użyliśmy do zdefiniowania clip-path
punkty i ujemna marża:
@keyframes load { 0%, 5% {width: var(--_d); } 95%, 100% {width: 100%; }
}
To trochę lepiej:
Ale możemy sprawić, że ta animacja będzie jeszcze płynniejsza. Czy zauważyłeś, że coś nam brakuje? Pokażę wam zrzut ekranu, aby porównać, jak powinna wyglądać ostateczna wersja demo z ostatnim demo:
To dolna ściana sześcianu! Ponieważ drugi element jest przezroczysty, musimy zobaczyć dolną powierzchnię tego prostokąta, jak widać w lewym przykładzie. Jest subtelny, ale powinien tam być!
Możemy dodać gradient do głównego elementu i przyciąć go tak, jak zrobiliśmy to z pseudosami:
background: linear-gradient(#fff1 0 0) bottom / 100% var(--_d) no-repeat;
Oto pełny kod, gdy wszystko jest już połączone:
.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%; }
}
Otóż to! Właśnie zastosowaliśmy sprytną technikę, która wykorzystuje pseudoelementy, stożkowe gradienty, przycinanie, mieszanie tła i ujemne marginesy, aby uzyskać nie jeden, ale drugiej słodko wyglądające ładowarki 3D z tylko jednym elementem w znacznikach.
Więcej 3D
Nadal możemy iść dalej i symulować nieskończoną liczbę kostek 3D za pomocą jednego elementu — tak, to możliwe! Oto siatka kostek:
To demo i następujące wersje demonstracyjne nie są obsługiwane w Safari w momencie pisania tego tekstu.
Szalony, prawda? Teraz tworzymy powtarzający się wzór kostek wykonanych z jednego elementu… i bez pseudosów! Nie będę wdawał się w szczegóły matematyki, której używamy (są tam bardzo konkretne liczby), ale oto rysunek, który zobrazuje, jak tu dotarliśmy:
Najpierw używamy a conic-gradient
aby utworzyć powtarzający się wzór kostki. Powtarzanie wzorca jest kontrolowane przez trzy zmienne:
--size
: Zgodnie ze swoją nazwą, kontroluje rozmiar każdej kostki.--m
: Reprezentuje liczbę kolumn.--n
: To jest liczba rzędów.--gap
: to szczelina lub odległość między kostkami
.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));
}
Następnie nakładamy warstwę maski za pomocą innego wzoru o tym samym rozmiarze. To najtrudniejsza część tego pomysłu. Korzystanie z kombinacji linear-gradient
oraz conic-gradient
wytniemy kilka części naszego elementu, aby widoczne były tylko kształty sześcianu.
.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;
}
Kod może wyglądać na nieco skomplikowany, ale dzięki zmiennym CSS wszystko, co musimy zrobić, to zaktualizować kilka wartości, aby kontrolować naszą macierz sześcianów. Potrzebujesz siatki 10⨉10? Zaktualizuj --m
i --n
zmienne do 10
. Potrzebujesz większej szczeliny między kostkami? Zaktualizuj --gap
wartość. Wartości kolorów są używane tylko raz, więc zaktualizuj je, aby uzyskać nową paletę kolorów!
Teraz, gdy mamy kolejną technikę 3D, wykorzystajmy ją do zbudowania wariacji modułu ładującego, bawiąc się różnymi animacjami. Na przykład, co powiesz na powtarzający się wzór sześcianów przesuwających się w nieskończoność od lewej do prawej?
Ta ładowarka definiuje cztery kostki w jednym rzędzie. To znaczy nasz --n
wartosc jest 4
i --m
jest równe 1
. Innymi słowy, już ich nie potrzebujemy!
Zamiast tego możemy pracować z --size
i --gap
zmienne w kontenerze siatki:
.loader { --size: 70px; --gap: 15px; width: calc(3 * (1.353 * var(--size) + var(--gap))); display: grid; aspect-ratio: 3;
}
To jest nasz pojemnik. Mamy cztery sześciany, ale chcemy pokazywać tylko trzy w pojemniku na raz, aby zawsze jeden wysuwał się, gdy jeden się wysuwa. Dlatego rozliczamy szerokość według 3
i ustaw proporcje na 3
, jak również.
Upewnijmy się, że nasz wzór sześcianu jest ustawiony na szerokość czterech sześcianów. Zrobimy to na kontenerze ::before
pseudoelement:
.loader::before { content: ""; width: calc(4 * 100% / 3); /* Code to create four cubes */
}
Teraz, gdy mamy cztery kostki w kontenerze z trzema kostkami, możemy uzasadnić wzór sześcianu do końca kontenera siatkowego, aby go przepełnić, pokazując ostatnie trzy kostki:
.loader { /* same as before */ justify-content: end;
}
Oto, co mamy do tej pory, z czerwonym konturem pokazującym granice kontenera siatki:
Teraz wystarczy przesunąć pseudoelement w prawo, dodając naszą animację:
@keyframes load { to { transform: translate(calc(100% / 4)); }
}
Znasz sztuczkę animacji? Zakończmy to, ukrywając przepełniony wzór sześcianu i dodając odrobinę maskowania, aby stworzyć efekt zanikania, który jest początkiem i końcem:
.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);
}
Możemy to znacznie uelastycznić, wprowadzając zmienną, --n
, aby ustawić liczbę kostek wyświetlanych w kontenerze jednocześnie. A ponieważ całkowita liczba kostek we wzorze powinna być o jeden więcej niż --n
, możemy to wyrazić jako calc(var(--n) + 1)
.
Oto cała sprawa:
OK, jeszcze jeden program ładujący 3D, który jest podobny, ale ma sześciany zmieniające kolejno kolor zamiast przesuwania się:
Będziemy polegać na animowanym tle z background-blend-mode
dla tego:
.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%; }
}
Usunąłem zbędny kod użyty do stworzenia takiego samego układu jak w poprzednim przykładzie, ale z trzema sześcianami zamiast czterech. Dodam tutaj gradient zdefiniowany określonym kolorem, który łączy się z gradientem stożkowym, tak jak to zrobiliśmy wcześniej w przypadku ładowania 3D paska postępu.
Stamtąd animuje gradient tła background-position
jako trzyetapową animację, która sprawi, że kostki będą migać kolorami pojedynczo.
Jeśli nie znasz wartości, których używam background-position
i składni tła, bardzo polecam jeden z moich poprzednich artykułów oraz jeden z podstawników moje odpowiedzi na przepełnienie stosu. Znajdziesz tam bardzo szczegółowe wyjaśnienie.
Czy możemy zaktualizować liczbę kostek, aby była zmienna?
Tak, mam rozwiązanie na to, ale chciałbym, żebyś spróbował tego, zamiast umieszczać go tutaj. Weź to, czego nauczyliśmy się z poprzedniego przykładu i spróbuj zrobić to samo z tym — następnie podziel się swoją pracą w komentarzach!
Obfitość odmian!
Podobnie jak w przypadku pozostałych trzech artykułów z tej serii, chciałbym pozostawić Wam inspirację do stworzenia własnych ładowarek. Oto kolekcja zawierająca ładowarki 3D, które wspólnie stworzyliśmy, a także kilka innych, które pobudzą Twoją wyobraźnię:
To jest okład
Mam nadzieję, że przez ostatnie kilka tygodni dobrze się bawiłeś, robiąc ze mną ładowacze pojedynczych elementów. To szalone, że zaczęliśmy od pozornie prostego spinnera, a następnie stopniowo dodawaliśmy nowe elementy, aby pracować samodzielnie aż do technik 3D, które wciąż używają tylko jednego elementu w znacznikach. Dokładnie tak wygląda CSS, gdy wykorzystamy jego moce: skalowalność, elastyczność i możliwość wielokrotnego użytku.
Jeszcze raz dziękujemy za przeczytanie tej krótkiej serii! Podpiszę się, przypominając, że mam zbiór ponad 500 ładowaczy jeśli szukasz więcej pomysłów i inspiracji.
Seria artykułów
- Ładowarki jednoelementowe: Spinner
- Ładowarki jednoelementowe: Dots
- Ładowarki jednoelementowe: Bary
- Ładowarki jednoelementowe: w 3D — jesteś tutaj
Ładowarki jednoelementowe: w 3D! pierwotnie opublikowany w dniu Sztuczki CSS. Powinieneś pobierz biuletyn.
- "
- 10
- 3d
- 9
- 95%
- a
- O nas
- w dodatku
- Wszystkie kategorie
- pozwala
- zawsze
- Inne
- Aplikuj
- na około
- artykuł
- towary
- tło
- bo
- zanim
- za
- Ulepsz Swój
- pomiędzy
- Bit
- budować
- Może uzyskać
- kod
- kolekcja
- połączenie
- kompleks
- Pojemnik
- zawartość
- kontrola
- kontroli
- Stwórz
- Tworzenie
- detal
- szczegółowe
- ZROBIŁ
- różne
- Wyświetlacz
- dystans
- Dropbox
- każdy
- efekt
- zapewniają
- itp
- wszystko
- dokładnie
- przykład
- odkryj
- Twarz
- twarze
- znajomy
- Postać
- w porządku
- i terminów, a
- elastyczne
- następujący
- od
- z przodu
- pełny
- dalej
- szczelina
- będzie
- Krata
- mający
- wysokość
- tutaj
- wysoko
- nadzieję
- W jaki sposób
- HTTPS
- pomysł
- pomysły
- wyobraźnia
- W innych
- obejmuje
- Inspiracja
- wprowadzenie
- IT
- Trzymać
- warstwa
- dowiedziałem
- Pozostawiać
- mało
- załadować
- Popatrz
- poszukuje
- zrobiony
- robić
- Dokonywanie
- maska
- matematyka
- Matrix
- znaczy
- jeszcze
- ruch
- ujemny
- numer
- z naszej
- Inne
- własny
- część
- Wzór
- sztuk
- gra
- zwrotnica
- możliwy
- poprzedni
- opublikowany
- Czytający
- polecić
- pozostały
- reprezentuje
- REST
- Safari
- taki sam
- skalowalny
- Serie
- zestaw
- Shape
- kształty
- Share
- pokazać
- znak
- podobny
- Prosty
- ponieważ
- pojedynczy
- Rozmiar
- So
- kilka
- coś
- Typ przestrzeni
- specyficzny
- Spędzanie
- dzielić
- Kwadratowa
- stos
- początek
- rozpoczęty
- rozpocznie
- Nadal
- Techniki
- Połączenia
- rzecz
- trzy
- czas
- razem
- Kontakt
- Przekształcać
- Przezroczystość
- przezroczysty
- Aktualizacja
- us
- posługiwać się
- wartość
- widoczny
- Co
- Podczas
- szerszy
- słowa
- Praca
- pisanie
- Twój