2014-11-18 13 views
7

Próbuję utworzyć 3d navbar za pomocą czystego CSS z transformacjami, przejściami i perspektywą.3D Navbar, który obraca się

Oto mój kod:

.navbar-fixed-bottom { 
 
\t background: transparent; 
 
\t } 
 
\t 
 
\t .navbar-perspective { 
 
\t width: 100%; 
 
\t height: 100%; 
 
\t position: relative; 
 
\t -webkit-perspective: 1100px; 
 
\t -moz-perspective: 1100px; 
 
\t perspective: 1100px; 
 
\t -webkit-perspective-origin: 50% 0; 
 
\t -moz-perspective-origin: 50% 0; 
 
\t perspective-origin: 50% 0; 
 
\t } 
 
\t 
 
\t .navbar-perspective > div { 
 
\t margin: 0 auto; 
 
\t position: relative; 
 
\t text-align: justify; 
 
\t -webkit-backface-visibility: hidden; 
 
\t -moz-backface-visibility: hidden; 
 
\t backface-visibility: hidden; 
 
\t -webkit-transition: all 0.5s; 
 
\t -moz-transition: all 0.5s; 
 
\t transition: all 0.5s; 
 
\t height: 50px; 
 
\t font-size:20px; 
 
\t } 
 
\t 
 
\t .navbar-primary { 
 
\t background-color: #cccccc; 
 
\t z-index: 2; 
 
\t -webkit-transform-origin: 0% 100%; 
 
\t -moz-transform-origin: 0% 100%; 
 
\t transform-origin: 0% 100%; 
 
\t } 
 
\t 
 
\t .navbar .navbar-secondary, 
 
\t .navbar .navbar-tertiary { 
 
\t background-color: #bfbfbf; 
 
\t width: 100%; 
 
\t -webkit-transform-origin: 0% 0%; 
 
\t -moz-transform-origin: 0% 0%; 
 
\t transform-origin: 0% 0%; 
 
\t z-index: 1; 
 
\t -webkit-transform: rotateX(-90deg); 
 
\t -moz-transform: rotateX(-90deg); 
 
\t transform: rotateX(-90deg); 
 
\t -webkit-transition: top 0.5s; 
 
\t -moz-transition: top 0.5s; 
 
\t transition: top 0.5s; 
 
\t position: absolute; 
 
\t top: 0; 
 
\t } 
 
\t 
 
\t .navbar .navbar-tertiary { 
 
\t background-color: #b3b3b3; 
 
\t } 
 
\t 
 
\t .navbar-rotate-primary { 
 
\t height: 50px; 
 
\t } 
 
\t 
 
\t .navbar-rotate-primary .navbar-primary { 
 
\t -webkit-transform: translateY(0%) rotateX(0deg); 
 
\t -moz-transform: translateY(0%) rotateX(0deg); 
 
\t transform: translateY(0%) rotateX(0deg); 
 
\t } 
 
\t 
 
\t .navbar-rotate-primary .navbar-secondary, 
 
\t .navbar-rotate-primary .navbar-tertiary { 
 
\t top: 100%; 
 
\t -webkit-transition: -webkit-transform 0.5s; 
 
\t -moz-transition: -moz-transform 0.5s; 
 
\t transition: transform 0.5s; 
 
\t -webkit-transform: rotateX(-90deg); 
 
\t -moz-transform: rotateX(-90deg); 
 
\t transform: rotateX(-90deg); 
 
\t } 
 
\t 
 
\t .navbar-rotate-secondary, 
 
\t .navbar-rotate-tertiary { 
 
\t height: 50px; 
 
\t } 
 
\t 
 
\t .navbar-rotate-secondary .navbar-primary, 
 
\t .navbar-rotate-tertiary .navbar-primary { 
 
\t -webkit-transform: translateY(-100%) rotateX(90deg); 
 
\t -moz-transform: translateY(-100%) rotateX(90deg); 
 
\t transform: translateY(-100%) rotateX(90deg); 
 
\t } 
 
\t 
 
\t .navbar-rotate-secondary .navbar-secondary, 
 
\t .navbar-rotate-tertiary .navbar-secondary { 
 
\t top: 100%; 
 
\t -webkit-transition: -webkit-transform 0.5s; 
 
\t -moz-transition: -moz-transform 0.5s; 
 
\t transition: transform 0.5s; 
 
\t -webkit-transform: rotateX(0deg) translateY(-100%); 
 
\t -moz-transform: rotateX(0deg) translateY(-100%); 
 
\t transform: rotateX(0deg) translateY(-100%); 
 
\t } 
 
\t 
 
\t .navbar-rotate-secondary-fallback .navbar-primary, 
 
\t .navbar-rotate-tertiary-fallback .navbar-primary { 
 
\t display: none; 
 
\t } 
 
\t 
 
\t .navbar-rotate-tertiary .navbar-secondary { 
 
\t -webkit-transform: translateY(-100%) rotateX(90deg); 
 
\t -moz-transform: translateY(-100%) rotateX(90deg); 
 
\t transform: translateY(-100%) rotateX(90deg); 
 
\t } 
 
\t 
 
\t .navbar-rotate-tertiary .navbar-tertiary { 
 
\t top: 100%; 
 
\t -webkit-transition: -webkit-transform 0.5s; 
 
\t -moz-transition: -moz-transform 0.5s; 
 
\t transition: transform 0.5s; 
 
\t -webkit-transform: rotateX(0deg) translateY(-100%); 
 
\t -moz-transform: rotateX(0deg) translateY(-100%); 
 
\t transform: rotateX(0deg) translateY(-100%); 
 
\t }
<html> 
 

 
<head> 
 

 
\t <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 

 
</head> 
 

 
<body> 
 

 
\t <nav id="navigation-bottom" class="navbar navbar-fixed-bottom"> 
 
\t \t <div class="navbar-perspective"> 
 
\t \t \t <div class="navbar-primary"> 
 
\t \t \t \t <a href="javascript:void(0);" onclick="$('#navigation-bottom').attr('class','navbar navbar-fixed-bottom navbar-rotate-secondary')">Rotate To Face 2</a> 
 
\t \t \t </div> 
 
\t \t \t <div class="navbar-secondary"> 
 
\t \t \t \t <a href="javascript:void(0);" onclick="$('#navigation-bottom').attr('class','navbar navbar-fixed-bottom navbar-rotate-tertiary')">Rotate To Face 3</a> 
 
\t \t \t </div> 
 
\t \t \t <div class="navbar-tertiary"> 
 
\t \t \t \t <a href="javascript:void(0);" onclick="$('#navigation-bottom').attr('class','navbar navbar-fixed-bottom navbar-rotate-primary')">Rotate Back To Face 1</a> 
 
\t \t \t </div> 
 
\t \t </div> 
 
\t </nav> 
 

 
</body> 
 

 
</html>

Mam pierwsze dwie twarze prawidłowo obracać za pomocą efektu 3D, ale trzeci twarz nie wygląda dobrze. Zauważysz, jak obracasz się od drugiego do trzeciego, że góra nie obraca się prawidłowo i wygląda płasko.

Każda pomoc jest bardzo doceniana.

+0

Oto JSFiddle: http://jsfiddle.net/wcb6kerq/ – Armin

Odpowiedz

-1

Po pierwsze, dziękuję wszystkim, którzy skomentowali i odpowiedzieli na to pytanie, zwłaszcza Josh!

Josh, twój przykład działa idealnie dla przeglądarek obsługujących preserve-3d. Aktualizacja, którą opublikowałeś bez zachowania-3d pojawia się płasko na IE, więc wciąż nie była doskonała we wszystkich przeglądarkach.

Po trzech dniach bólów głowy zdałem sobie sprawę z tego problemu. Początek boków nie został poprawnie ustawiony. Boki muszą obracać się wokół punktu, który jest w połowie drogi do osi Z.

Raz Zaktualizowaliśmy pochodzenie do:

transform-origin: 25px 25px -25px; 

Kiedy to było prawidłowe, wszystko co naprawdę trzeba zrobić, to zaktualizować obrót obiektu. Nie trzeba używać żadnych przekształceń współrzędnych X, Y, Z.

Oto skrzypce i rozwiązanie dla paska nawigacyjnego 3D, który obraca się i działa dla wszystkich przeglądarek, w tym IE10 +.

http://jsfiddle.net/tx0emcxe/

+0

Josh, twój przykład na IE nie ma perspektywy. To jak patrzenie na obiekt 3D z przodu. Kiedy boki się obracają, boki nie przesuwają się w kierunku środka, przez co wyglądają płasko. – Armin

+1

@misterManSam - Masz absolutną rację i jestem w pełni świadomy. Jednak czuję się trochę zirytowany postawą pytającego i naleganiem, że moja odpowiedź była w jakiś sposób niepełna, nawet w jego własnej, zaakceptowanej odpowiedzi. Nie martwią się tak bardzo, że przyznano nagrodę. W trosce o to, że nie jestem tu nieistotny dla społeczności, usunąłem moje komentarze. Punkt wzięty. –

7

Fiddle with a flipping box

To znacznie różni się od miejsca startu, ale pozwól mi pisać mój CSS i pokazać na skrzypcach, a potem będę zmieniać w dłuższym wyjaśnienia, jak i dlaczego to działa:

 

HTML

<section class="container"> 
    <nav id="nav-box" class="show-front"> 
     <div class="front"> 
      <a href="#">Show Bottom</a> 
     </div> 
     <div class="bottom"> 
      <a href="#">Show Back</a></div> 
     <div class="back"> 
      <a href="#">Show Top</a></div> 
     <div class="top"> 
      <a href="#">Show Front</a></div> 
    </nav> 
</section> 

 

CSS

.container { 
    position: relative; 
    perspective: 1000px; 
    transform: scale(0.95); 
} 

#nav-box { 
    width: 100%; 
    height: 50px; 
    position: absolute; 
    transform-origin: center center; 
    transform-style: preserve-3d; 
    transition: transform 0.5s; 
} 

#nav-box div { 
    width: 100%; 
    height: 50px; 
    display: block; 
    position: absolute; 
    transition: background-color 0.5s; 
} 

#nav-box .front { transform: rotateX( 0deg) translateZ(25px); background-color: #ccc; } 
#nav-box .back { transform: rotateX(180deg) translateZ(25px); background-color: #ccc; } 
#nav-box .top { transform: rotateX( 90deg) translateZ(25px); background-color: #ccc; } 
#nav-box .bottom { transform: rotateX(-90deg) translateZ(25px); background-color: #ccc; } 

#nav-box.show-front { transform: rotateY( 0deg); } 
#nav-box.show-front .bottom { background-color: #a0a0a0; } 
#nav-box.show-front .top { background-color: #e0e0e0; } 
#nav-box.show-back { transform: rotateX(-180deg); } 
#nav-box.show-back .bottom { background-color: #e0e0e0; } 
#nav-box.show-back .top { background-color: #a0a0a0; } 
#nav-box.show-top { transform: rotateX( -90deg); } 
#nav-box.show-top .front { background-color: #a0a0a0; } 
#nav-box.show-top .back { background-color: #e0e0e0; } 
#nav-box.show-bottom { transform: rotateX( 90deg); } 
#nav-box.show-bottom .front { background-color: #e0e0e0; } 
#nav-box.show-bottom .back { background-color: #a0a0a0; } 

 

Wyjaśnienie HTML/CSS

Konfigurowanie naszą skrzynkę

zacząłeś myśleć o tym w niewłaściwy sposób, ja nie lubię mówić. Podszedłeś do tego jako "Jak mogę traktować te cztery boki jak pudełko", zamiast "Jak utworzyć skrzynkę w CSS?"

Zobaczmy, jak zrobić pudełko.

Najpierw zakładamy kontener box. Ponieważ jest to pole nawigacji, nazwijmy to: nav-box. Wszystkie transformacje, które zastosujemy (z wyjątkiem cieniowania, które otrzymamy później) zostaną wykonane na naszej nav-box.

Reguły dotyczące naszego nav-box określają, jak zachowuje się on jako obiekt. Porozmawiajmy o dwóch w szczególności: transform-origin i transform-style

transform-origin domyślnie centrum centrum, ale chciałem go tutaj wywołać. To w zasadzie powie nam nasze pudełko: Hej, potrzebujemy was obrócić wokół waszego absolutnego centrum. Jeśli ustawimy to jako transform-origin: center bottom' it would look like the box is spinning around its bottom edge. center top` i obróci się wokół swojej górnej krawędzi. Nie sądzę, że tego właśnie chcesz.

transform-style należy ustawić na preserve-3d. To, co robi, to poinstruuj przeglądarkę, aby nie mieszała się z elementami pod transform.Inne opcje to flat, które mówi przeglądarce, aby ignorować obraca się pod nim. Powodem, dla którego chcemy ustawić preserve-3d na naszej nav-box tutaj jest zapewnienie, że transforms, które zastosowaliśmy do boków pudełka, zostanie zachowane, gdy będziemy rodzicem transform. Cholerne rzeczy, co?

Konfigurowanie nasze strony

Jesteśmy ustawienie naszych stronach jako dzieci naszych nav-box i po prostu umieszczając je w kolejności, w jakiej powinny być one w użyciu rotateX:

  • 0 obrotu dla przód
  • 180deg z tyłu
  • -90deg na dole
  • 90deg dla górnej

Możemy również ustawić lewej i prawej strony teraz z .left { transform: rotateY(-90deg); } .right { rotateY(90deg); }. Zauważ, że użyliśmy osi Y dla tych dwóch przykładów.

Po drugie, ustawiamy wartość translateZ z 25px. Co to do cholery robi? Mówi naszym boksom, że muszą przenieść 25px ze środka rodzica względem ich odpowiednich obrotów. Dlaczego wybraliśmy 25px? Ponieważ to dokładnie połowa wysokości każdego z naszych pudełek. Oznacza to, że będzie ładnie przepłukiwał się bokami przy każdej krawędzi.

A potem zabawa:

Mamy odcień pola w oparciu o ich położeniu i co stoi ekran. Kolory tła są zależne od tego, po której stronie pudełka wyświetlana jest taśma, która jest z boku. Dno na dole robi się ciemniejsze, strona na górze staje się jaśniejsza. Po prostu to lubiłem - zupełnie nie jest to konieczne, aby wykonać to zadanie, ale sprawia, że ​​wygląda trochę bardziej realistycznie.

Nadzieję, że pomaga!

 


Aktualizacja IE

Fiddle Example

Tak, nie ma tam wiele całkiem o tym raz otrzymujemy poprzez ustalenie go na IE, ale tutaj jest. Wszystko, co robi preserve-3d, polega na stosowaniu transformacji, gdy obracamy pojemnik zamiast je spłaszczać. Jeśli nie możemy użyć preserve-3d, musimy obliczyć na podstawie całkowitej rotacji.

To rozwiązanie to robi. Nie pójdę za dogłębne na ten jeden, zamiast podkreślić, jak wiele więcej JavaScript Wymaga to, aby wyróżnić i klasę .rewind:

#nav-box.rewind div { 
    backface-visibility: hidden; 
} 

Ponieważ musimy ręcznie przewinąć to rozwiązanie, będziemy muszą uniemożliwić zmianę kolejności indeksu Z w niewłaściwym czasie. W tym miejscu przychodzi backface-visibility.

Example showing depth in IE

Another example without the need for the rewind class

nadzieję, że rozwiązuje IE dla Ciebie.

+0

Dzięki za odpowiedź, ale to nie działa w IE, ponieważ używasz właściwość preserve3d. Sztuką jest NIE używać tej właściwości. – Armin

+0

@Armin - Sprawdź edycję. Dałem ci poprawkę kwalifikującą się do IE. –

+0

Lepiej, działa dla IE, ale perspektywa jest płaska. – Armin