2016-05-26 47 views
11

Próbowałem utworzyć ten efekt przy użyciu przejść. Powinno to wyglądać jak otwierasz pudełko.Tworzenie efektu klapki otwartej przy użyciu tylko CSS

Są 2 problemy:

  1. Kolejność, w której zamyka okno jest taka sama jak w który otwiera. Czy mimo to należy zamknąć pudełko w odwrotnej kolejności od jego otwarcia, aby pudełko powróciło w tym samym stanie, w którym było zamknięte?
  2. Końce zielonych i żółtych klapek są ukryte podczas przejścia z powodu czerwonych i niebieskich klap, więc nie wygląda 3D. Czy istnieje sposób, w jaki mogę pokazać wszystkie klapy w 3D?

Wolałbym, jeśli rozwiązanie było w czystym CSS, proszę JavaScript.

#box { 
 
    position: relative; 
 
    top: 170px; 
 
    left: 170px; 
 
    width: 300px; 
 
    height: 300px; 
 
    border: 1px solid black; 
 
    perspective: 800px; 
 
} 
 
#flap1, #flap2, #flap3, #flap4 { 
 
    position: absolute; 
 
} 
 
#flap1 { 
 
    background-color: red; 
 
    width: 150px; 
 
    height: 300px; 
 
    z-index: 1; 
 
    transform-origin: 0 0; 
 
    transition: transform 1s; 
 
} 
 
#flap2 { 
 
    left: 150px; 
 
    background-color: blue; 
 
    width: 150px; 
 
    height: 300px; 
 
    z-index: 1; 
 
    transform-origin: 100% 0; 
 
    transition: transform 1s ease 0.3s; 
 
} 
 
#flap3 { 
 
    background-color: green; 
 
    width: 300px; 
 
    height: 150px; 
 
    transform-origin: 0 0; 
 
    transition: transform 1s ease 0.6s; 
 
} 
 
#flap4 { 
 
    background-color: yellow; 
 
    top: 150px; 
 
    width: 300px; 
 
    height: 150px; 
 
    transform-origin: 0 100%; 
 
    transition: transform 1s ease 0.9s; 
 
} 
 
#box:hover #flap1{ 
 
    transform: rotateY(-170deg); 
 
} 
 
#box:hover #flap2{ 
 
    transform: rotateY(170deg); 
 
} 
 
#box:hover #flap3{ 
 
    transform: rotateX(170deg); 
 
} 
 
#box:hover #flap4{ 
 
    transform: rotateX(-170deg); 
 
}
<html> 
 
    <head> 
 
    <link rel="stylesheet" href="style.css"> 
 
    </head> 
 
    <body> 
 
    <div id="box"> 
 
     <div id="flap1"></div> 
 
     <div id="flap2"></div> 
 
     <div id="flap3"></div> 
 
     <div id="flap4"></div> 
 
    </div> 
 
    </body> 
 
</html>

+0

1. Myślę, że nie można. Po prostu dodaj kolejną klasę lub coś. 2.Możesz użyć css3 ['perspective'] (http://www.w3schools.com/cssref/css3_pr_perspective.asp) –

Odpowiedz

8

Dla Pytanie 1:

Jeśli dasz opóźnienie w celu naprzód dla :hover selektorów i w odwrotnej kolejności w domyślnych selektorów, będzie to osiągnąć dokładnie odwrotnie animacja.

Dla Pytanie 2:

Rozwiązaniem i wyjaśnienia są następujące:

  • przez część czasu trwania przejścia, zielone i żółte pola nie wyglądają tak, jakby mieć efekt 3D ponieważ jest kilka elementów z wyższą wersją z-index, która jest umieszczona powyżej. Zapobiega to wyświetlaniu się rozciągniętego obszaru (z powodu obrócenia perspektywy), a zatem wygląda na to, że jest tylko 2D (podczas gdy tak naprawdę nie jest). Aby temu zaradzić, musimy poinstruować przeglądarki, aby zachowały aspekt 3D transformacji. Odbywa się to za pomocą transform-style: preserve-3d.
  • Kiedy to zrobimy, wszystkie klapy będą otwierane z efektem 3D, ale w pobliżu początku animacji i jej końca zobaczymy migotanie na niebieskiej klapie, kiedy przejście faktycznie zaczyna się i kończy dla niebieskiej klapy. Wygląda na to, ponieważ z-index traci skuteczność, gdy używana jest transformacja 3D, a pomiędzy utratą efektu z-index i początkiem efektu preserve-3D pojawia się niewielki czas, w trakcie którego niebieska klapa tymczasowo przechodzi w tył. Aby rozwiązać ten problem, dodano 3D odpowiednik z-index: 1 (który jest, translateZ(1px)). Translate w osi Z zbliża element o 1 piksel do twojego oka i utrzymuje go ponad żółtymi i zielonymi klapami.
  • Na koniec, mimo wszystkich powyższych, pojawia się niewielki błąd na końcu animacji, gdzie zielona klapka pokazuje niebieską klapkę. Aby temu zaradzić, trochę zmieniłem czasy opóźnień.

(W przeciwieństwie do tego, co pierwotnie wspomniano, translateZ(0px) nie jest konieczne i może zostać usunięta.)

#box { 
 
    position: relative; 
 
    top: 170px; 
 
    left: 170px; 
 
    width: 300px; 
 
    height: 300px; 
 
    border: 1px solid black; 
 
    perspective: 800px; 
 
    transform-style: preserve-3d; 
 
} 
 
#flap1, #flap2, #flap3, #flap4 { 
 
    position: absolute; 
 
} 
 
#flap1 { 
 
    background-color: red; 
 
    width: 150px; 
 
    height: 300px; 
 
    z-index: 1; 
 
    transform: translateZ(1px); 
 
    transform-origin: 0 0; 
 
    transition: transform 1s 1.5s; 
 
} 
 
#flap2 { 
 
    left: 150px; 
 
    background-color: blue; 
 
    width: 150px; 
 
    height: 300px; 
 
    z-index: 1; 
 
    transform: translateZ(1px); 
 
    transform-origin: 100% 0; 
 
    transition: transform 1s ease 1s; 
 
} 
 
#flap3 { 
 
    background-color: green; 
 
    width: 300px; 
 
    height: 150px; 
 
    transform-origin: 0 0; 
 
    transition: transform 1s ease 0.5s; 
 
} 
 
#flap4 { 
 
    background-color: yellow; 
 
    top: 150px; 
 
    width: 300px; 
 
    height: 150px; 
 
    transform-origin: 0 100%; 
 
    transition: transform 1s ease; 
 
} 
 
#box:hover #flap1 { 
 
    transform: rotateY(-170deg) translateZ(1px); 
 
    transition: transform 1s ease; 
 
} 
 
#box:hover #flap2 { 
 
    transform: rotateY(170deg) translateZ(1px); 
 
    transition: transform 1s ease 0.5s; 
 
} 
 
#box:hover #flap3 { 
 
    transform: rotateX(170deg); 
 
    transition: transform 1s ease 1s; 
 
} 
 
#box:hover #flap4 { 
 
    transform: rotateX(-170deg); 
 
    transition: transform 1s ease 1.5s; 
 
}
<div id="box"> 
 
    <div id="flap1"></div> 
 
    <div id="flap2"></div> 
 
    <div id="flap3"></div> 
 
    <div id="flap4"></div> 
 
</div>

+0

Dobrze rozwiązanie pierwszego pytania było świetne i chociaż drugie rozwiązanie działa dobrze, nie rozumiem, jak z- indeks rozwiązuje problem .... widzisz, jeśli wskaźnik Z klatek czerwonych i niebieskich to 1px, czyli więcej niż zielone i żółte pole, to nie powinien dominować drugi problem, ponieważ zielone i żółte pola są nadal poniżej czerwonego i niebieskiego pudełko? @Harry –

+0

@DhruvChadha: 'translateZ()' robi prawie to samo co "z-index" dla scenariusza 3D. Masz rację mówiąc, że zielony i żółty nadal są poniżej niebieskiego i czerwonego, ale dodanie transformacji 3D powoduje utworzenie warstwy (części skomplikowanego procesu renderowania), która wpływa na zachowanie. Trudne do wyjaśnienia w komentarzach. Postaram się szczegółowo opisać to w odpowiedzi. Daj mi trochę czasu. – Harry

+1

@DhruvChadha: Dodałem kilka dodatkowych wyjaśnień (i skorygowałem błąd także z oryginalnej odpowiedzi: D). Zobacz, czy to pomaga :) – Harry