Animacja 3d w css możliwa już od wersji IE10, za pomocą przychodzi nam parametr perspective.
Nasza animacja będzie polegała na obracaniu sześcianu. Jak wiemy sześcian to sześć ścian więc zaczniemy od nich.
<div class="scene">
<div class="cube">
<div class="cube__wall cube__front">front</div>
<div class="cube__wall cube__back">back</div>
<div class="cube__wall cube__right">right</div>
<div class="cube__wall cube__left">left</div>
<div class="cube__wall cube__top">top</div>
<div class="cube__wall cube__bottom">bottom</div>
</div>
</div>
Jak widać nic szczególnego, scene - która zawiera div [cube] wraz z sześcioma ścianami. Każda ze ścian posiada napis tak aby można było zauważysz rotację tej kostki.
Teraz same "mięsko" a mianowicie css. Zaczynamy od podstaw zbudowanie podstaw, body na 100% wysokości do tego dodam animację backgroundu - tutaj wykorzystałem z generatora gradientów
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
background-color: #f0f0f0;
background-image: linear-gradient(to right bottom, #051937, #004a7b, #0081a0, #00b993, #12eb54);
background-size: 200% 200%;
animation: animationGradient 5s ease infinite;
}
@keyframes animationGradient {
0% {
background-position: 10% 0%
}
50% {
background-position: 91% 100%
}
100% {
background-position: 10% 0%
}
}
Teraz najważniejszy element, css odpowiedzialny za wygląd sześcianu.
.scene {
width: 200px;
height: 200px;
margin: 100px;
perspective: 400px;
}
.cube {
width: 200px;
height: 200px;
position: relative;
transform-style: preserve-3d;
transform: translateZ(-100px);
}
.cube__wall {
position: absolute;
width: 200px;
height: 200px;
border: 3px solid #000;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
font-size: 2rem;
text-transform: uppercase;
color: #fff;
}
.cube__front {
background: rgba(255, 0, 0, 0.6);
transform: rotateY(0deg) translateZ(100px);
}
.cube__back {
background: rgba(0, 38, 255, 0.6);
transform: rotateY(180deg) translateZ(100px);
}
.cube__right {
background: rgba(0, 255, 33, 0.6);
transform: rotateY(90deg) translateZ(100px);
}
.cube__left {
background: rgba(105, 101, 37, 0.6);
transform: rotateY(-90deg) translateZ(100px);
}
.cube__top {
background: rgba(255, 0, 233, 0.6);
transform: rotateX(90deg) translateZ(100px);
}
.cube__bottom {
background: rgba(251, 255, 0, 0.6);
transform: rotateX(-90deg) translateZ(100px);
}
W klasie scene musimy ustawić perspective: 400px; Parametr ten daje nam głębie 3d. Warto nim się pobawić i zobaczyć jak zmienia się perspektywa w zależności ile ustawimy px.
Klasa cube składa się z transform-style: preserve-3d; Ta właściwość ustala, że elementy potomne - dzieci znajdują się w tej samej perspektywie co element nadrzędny.
Klasa cube__wall ustawia nam wszystkie ściany jako absolute, inaczej nie moglibyśmy zmieniać położenia za pomocą
rotateY, rotateX oraz translateZ, klasa ta posiada również pozycjonowanie napisów [front, bottom, left, right, back].
Reszta klas odpowiada za pozycję 'ścian'. Każda ze ścian posiada kolor z transparentnością ustawioną na 0.6.
Do pełni szczęścia brakuje nam animacji naszego sześcianu 😉
Tutaj do klasy cube dodamy animation: rotationCube 10s infinite ease-in-out
Animacja nazywa się rotationCube trwającą 10s, infinitie czyli w nieskończoność powtarzana, a ease-in-out jest rodzajem animacji.
.cube {
width: 200px;
height: 200px;
position: relative;
transform-style: preserve-3d;
transform: translateZ(-100px);
animation: rotationCube 10s infinite ease-in-out;
}
@keyframes rotationCube {
0% {
transform: translateZ(-100px) rotateX(0deg) rotateY(0deg);
}
50% {
transform: translateZ(50px) rotateX(-360deg) rotateY(-360deg);
}
100% {
transform: translateZ(-100px) rotateX(0deg) rotateY(360deg);
}
}
Poniżej cały działający przykład. polecam pobawić się ustawieniami. Np. do klasy cube__wall dodać box-shadow box-shadow: 0 0 0 20px rgba(255, 255, 255, 0.5) bardzo ciekawy efekt 😉
See the Pen
3D animation by Greg (@Tomik23)
on CodePen.