chevron-left chevron-right

[CSS][JS] Jak utworzyć animowane trójwymiarowe obiekty w CSS?

Do tej pory, animacje 3D kojarzyły się najczęściej z grami komputerowymi lub filmami. Do ich utworzenia wykorzystywano zupełnie inne języki programowania niż CSS czy JS. Na szczęście, obecny postęp technologiczny i rozwoju języków webowych pozwala na utworzenie obiektów 3D czy animacji 3D już za pomocą CSS.
Co ciekawe, wykorzystanie CSS sprawia, że wykorzystujemy moc karty graficznej, czyli nie potrzebujemy dodatkowego oprogramowania, które będzie odpowiedzialne za generowanie efektów, tak jak np. ma to miejsce we Flashu.

W tym wpisie zostanie omówiony sposób uzyskania trójwymiarowego sześcianu (kostki), a następnie animowania jej w oknie przeglądarki.

Szkielet sześcianu w HTML

Aby zbudować strukturę HTML dla sześcianu potrzebujemy 7 elementów: kontenera na kostkę i 6 ścian. Kod HTML, który spełnia te założenia wygląda następująco:

1
2
3
4
5
6
7
8
  <div class="cube">
    <div class="top"></div>
    <div class="right"></div>
    <div class="bottom"></div>
    <div class="left"></div>
    <div class="front"></div>
    <div class="back"></div>
  </div>

Zdefiniowano kontener dla kostki (.cube), a wewnątrz niego dodano 6 divów, które będą pełniły rolę ścian.

Wygląd sześcianu w CSS3

Tak przygotowaną strukturę HTML należy ostylować, tak aby zaczęło to wszystko przypominać kostkę sześcienna. Wykorzystamy tu kilka właściwości CSS, które potrzebują prefiksów, aby działały w większej liczbie przeglądarek internetowych. Dla zwiększenia czytelności, przykłady będę omawiał na wartościach bez prefiksów.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
.cube {
  display: block;
  position: relative;
  width: 108px;
  height: 108px;
  margin: 0 31px;
  float: left;
  transform-style: preserve-3d; /* --- prefix --- */
  transition: all 1.5s ease 0s; /* --- prefix --- */
}
.cube > div {
  background-size: cover;
  height: 100%;
  overflow: hidden;
  position: absolute;
  width: 100%;
  opacity: 0.9;
}
.cube .front {
  background: url('logo.png') no-repeat;
  transform: rotate3d(0, 1, 0, 0deg) translate3d(0, 0, 54px);   /* --- prefix --- */
}
.cube .back {
  background: #bb3300;
  transform: rotate3d(1, 0, 0, 180deg) translate3d(0, 0, 54px); /* --- prefix --- */
}
.cube .top {
  background: #f04100;
  transform: rotate3d(1, 0, 0, 90deg) translate3d(0, 0, 54px);  /* --- prefix --- */
}
.cube .right {
  background: #222;
  transform: rotate3d(0, 1, 0, 90deg) translate3d(0, 0, 54px);  /* --- prefix --- */
}
.cube .bottom {
  background: #f04100;
  transform: rotate3d(1, 0, 0, -90deg) translate3d(0, 0, 54px); /* --- prefix --- */
}
.cube .left {
  background: #222;
  transform: rotate3d(0, 1, 0, -90deg) translate3d(0, 0, 54px); /* --- prefix --- */
}

Klasa cube jest kontenerem dla ścianek kostki. W niej ustawiono 2 ciekawe własności: transform-style oraz transition. Pierwsza z nich jest odpowiedzialna za zdefiniowanie stylu przeprowadzanych transformacji na strukturze HTML, a druga z nich jest odpowiedzialna za tworzenie animacji przejścia między stanami obiektu (w tym przypadku, sprawdza wszystkie własności i animuje zmiany między ich wartościami).

Wewnątrz kostki zdefiniowano ścianki i każda z nich ma określony kolor oraz położenie względem osi XYZ. Własność transform przyjmuje dwie wartości w postaci funkcji: rotate3d oraz translate3d.
Funkcja rotate3d jest odpowiedzialna za "okręcenie" elementu względem osi XYZ, natomiast funkcja translate3d odpowiada za przesunięcie elementu w głębi.

Animowanie kostki za pomocą JS

Aby tak przygotowany element strony nabrał życia należy utworzyć skrypt, który będzie powodował animację między właściwościami elementu. Taki skrypt, napisany w JS, może wyglądać następująco:

$(function() {
  // znajdź wszystkie elementy z klasą cube
  var cubes       = $('.cube');
  // nazwa właściwości CSS, której wartości będziemy zmieniać
  var propertyName= 'transform';
  // prefiksy dla różnych wersji przeglądarek
  var prefix      = ['-webkit-', '-moz-', '-o-', '-ms-', ''];
 
  // uruchamiamy pętlę czasową, która trwa 1,4 sek.
  setInterval(function() {
 
    //dla każdego elementu/kostki
    cubes.each(function() {
      // oblicz wartości przesunięcia względem osi, kolejno: OX, OY, OZ oraz margines górny
      var rotateX   = parseInt(Math.floor(Math.random() * (720 - 1 + 1)) + 1, 10) + 'deg';
      var rotateY   = parseInt(Math.floor(Math.random() * (720 - 1 + 1)) + 1, 10) + 'deg';
      var rotateZ   = parseInt(Math.floor(Math.random() * (720 - 1 + 1)) + 1, 10) + 'deg';
      var marginTop = parseInt(Math.floor(Math.random() * (432 - 1 + 1)) + 1, 10) + 'px';
 
      // obiekt, ktory będzie zawierał nowe właściwości
      var properties = {'margin-top' : marginTop};
 
      // utwórz właściwość CSS sprefiksowaną, dzięki temu większa liczba przeglądarek będzie w stanie obsłużyć animację
      $.each(prefix, function(i, k) {
        properties[k + propertyName] = 'rotateY(' + rotateY + ') rotateX(' + rotateX + ') rotateZ(' + rotateZ + ')';
      });
 
      // przypisz nowo utworzonoe właściwości do obiektu
      $(this).css(properties);
 
    });
  }, 1400);

Każdą animację odpalamy co 1.4 sekundy. Jeśli dobrze się przypatrzysz, to w CSS zdefiniowaliśmy czas trwania animacji na 1.5 sekundy. Krótszy czas interwału zdefiniowanego w JS pozwoli na zachowanie płynności między kolejnymi stanami.

Powyższy kod JS został opisany komentarzami.

Podsumowanie informacji o animacjach 3D w CSS

Powyższy przykład kodu HTML, CSS i JS ma za zadanie uświadomić Ciebie, że tworzenie animacji 3D nie jest trudne. Jedynym ograniczeniem może być wsparcie przeglądarek.

Przeglądarka wsparcie
Mozilla Firefox tak
Google Chrome tak
Opera nie
Safari tak
Internet Explorer

7/8/9/10

nie

Jeśli jednak wsparcie dla przeglądarek nie jest najważniejszym czynnikiem użyteczności danego rozwiązania, to nic nie stoi na przeszkodzie aby dać ponieść się swojej kreatywności i stworzyć coś naprawdę ciekawego, niespotykanego.

Demo z tego artykułu możesz zobaczyć pod tym linkiem: animacje 3D w CSS