最近在練習CSS3動畫。做了兩個小 demo,一個是六面體的旋轉,一個是翻紙牌的小 demo。特此再次總結一下自己的思路,以及踩過的坑。O(∩_∩)O
六面體旋轉的思路
首先我們來說一下關于六面體的旋轉,可以化解兩個步驟:
1.構建六面體
2.旋轉六面體
其實第二個步驟很好做,旋轉只需要用 transform rotateX rotateY rotateZ 就可以了。所以關鍵是在我們如何構建一個六面體。
一、構建六面體
首先我們建立六個面,并將它包裹在一個 div 里面
<div class="wrap">
<div class="front">前</div>
<div class="back">后</div>
<div class="right">右</div>
<div class="left">左</div>
<div class="top">上</div>
<div class="bottom">下</div>
</div>
但是這個樣子,會造成六個 div 是并排排下來的,所以我們設置這些 div 的定位為絕對定位,這樣,六個面就重合了,中心在在同一個點:
.wrap > div{
display:block;
position:absolute;
width:100px;
height:100px;
line-height:100px;
text-align:center;
font-size:60px;
color:white;
}
根據上面 3D 的 XYZ 軸,想象一下,六面體前面和后面兩個是正對著我們的,所以他不需要進行任何旋轉的工作。但是,左邊那個面應該是向上旋轉90度的,也就是向 Y 軸旋轉,而右邊那個面則是向Y軸旋轉-90度啦,這樣他兩個面就相對了。接下來就是旋轉上下兩個面,朝著 X 軸旋轉90度和-90度。設置好六個面之后,接下來就是設置每個面的透視的位置啦。因為我設置的六面體的長和寬是100px,我以六面體的中心為軸,所以前面這個面我設置的 translateZ 為50px,那么后面那個面自然九尾-50px了。剩下的四個面應該都是50px,因為他們都連著‘’前面‘’。最后形成代碼如下:
.front{
border:none;background:rgba(0,0,0,0.3);
-webkit-transform:translateZ(50px);
transform:translateZ(50px);
}
.back{
background:rgba(0,255,0,1);
-webkit-transform:translateZ(-50px);
transform:translateZ(-50px);
}
.right{
background:rgba(196,0,0,0.7);
-webkit-transform:rotateY(90deg) translateZ(50px);
transform:rotateY(90deg) translateZ(50px);
}
.left{
background:rgba(0,0,196,0.7);
-webkit-transform:rotateY(-90deg) translateZ(50px);
transform:rotateY(-90deg) translateZ(50px);
}
.top{
background:rgba(196,196,0,0.7);
-webkit-transform:rotateX(90deg) translateZ(50px);
transform:rotateX(90deg) translateZ(50px);
}
.bottom{
background:rgba(196,0,196,0.7);
-webkit-transform:rotateX(-90deg) translateZ(50px);
transform:rotateX(-90deg) translateZ(50px);
}```
接下來咱們設置重點:`perspective`。
因為咱們將六個面都包在一個 *wrap* 里面,所以咱們實際上是看wrap這個div。*所以我們需要對 *wrap* 設置`transform-style:preserve-3d;`(這個代表你看大的是2d還是3d)*。根據 [我查閱的資料](http://www.zhangxinxu.com/wordpress/2012/09/css3-3d-transform-perspective-animate-transition/ )
正方體透視中心應該為`perspective-origin: 25% 75%;`

重點來了:設置`perspective`.起初,我設置了,`perspective`的值為250px,這樣,也沒多大問題,但是可以很明顯的看出,后面比前面從眼睛看上去比較小,導致在旋轉的時候,六個面在旋轉的時候都變形了,唄拖了很長。這個時候,是透視距離太小了,導致后面的面與前面的面差太多,于是旋轉的時候就變形。當我把透視(perspective)設的距離大一點的時候,當我設的距離為660px的時候,前后兩個面基本一樣大小,旋轉的時候也不會變形。其實,還有一種方法,就是不設perspective視點。這樣也不會產生變形。因為這整個正方體圍繞中心旋轉,不管哪個面轉到了前面,都是相對一開始的位置并沒有變化。反之,如果按照某個特定端點來轉動,正方體的位置會發(fā)生變化,這樣就導致了每個面就有視差。但是這樣的話,旋轉到最后的時候,前面和后面兩個面是重合了O(∩_∩)O
######二、旋轉六面體
旋轉就比較簡單了,就是讓沃恩的 *wrap* 區(qū)域轉動。動畫如下:
@keyframes run{
0%{
transform:rotateX(0deg) rotateY(0deg) rotateZ(0deg);
transform-origin: center center;
}
100%{
transform:rotateX(180deg) rotateY(180deg) rotateZ(180deg);
transform-origin: center center;
}
}
隨后將這個動畫綁定到wrap上就行啦。
這樣旋轉六面體就講完啦。接下來我們說一下翻轉紙牌效果:~~
####紙牌翻轉的思路
整體的思路可以分為如下幾個步驟:
1.設計布局方式和排版
2.編寫兩張紙牌擺放位置
3.編寫紙牌翻轉效果
#####一、設計布局方式和排版
這次布局采用flex布局,這個的排版的形式是第一行擺放三張牌,第二行擺放兩張牌
#####二、編寫兩張紙牌擺放位置
兩張牌應該也是中心重合的,所以需要對著兩張牌設置 *position* 的位置為 *absolute*,并且,為了效果一致,這兩張牌的寬度和長度最好保持一致。
并且設置第一章牌的 *z-index* 為2,第二章牌的 *z-index* 為1,這樣我們就能看見靜態(tài)擺放著的是第一張牌,實際上第二章牌放在他下面。O(∩_∩)O
#####三、編寫紙牌翻轉效果
假設希望牌是沿著Y軸旋轉的,也就是沃恩口中常說的,豎著轉~,所以,我們默認第一張牌他不轉動任何角度,即 *rotateY(0)*,讓第二章牌反著放,也就是 *rotateY(180deg)*,這樣,當我鼠標點擊或移動到第一張牌的,讓第二排的角度變?yōu)?度,這樣,從反面沿著 *Y* 軸轉到正面,就是我們想要的效果啦。代碼如下:
/*正面*/
.poke_one{
background:url(../image/poke.jpg) no-repeat;
background-size:100% 100%;width: 15rem;
height:20rem;
position: absolute;
z-index:2;
-webkit-transform: rotateY(0);
-moz-transform: rotateY(0);
-ms-transform: rotateY(0);
transform: rotateY(0);
}
/*反面*/
.poke_two{
width: 15rem;
height:20rem;
background: #99cc33;
position: absolute;
z-index:1;
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
transform: rotateY(180deg);
-ms-transform: rotateY(180deg);
color:#fff;
font-weight: bold;
line-height: 20rem;
text-align: center;
font-size: 3.2rem;
}
/*準備翻牌*/
.wrap>div{
perspective:200px;
-webkit-perspective:200px;
-moz-perspective:200px;
-ms-perspective:200px;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
-webkit-transition:0.8s ease-in-out ;
-moz-transition:0.8s ease-in-out ;
-ms-transition:0.8s ease-in-out ;
}
.wrap:hover>.poke_one{
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
-ms-transform: rotateY(180deg);
transform: rotateY(180deg);
}
.wrap:hover>.poke_two{
-webkit-transform: rotateY(0);
-moz-transform: rotateY(0);
-ms-transform: rotateY(0);
transform: rotateY(0);
}
大家有的可能會很好奇`-webkit-backface-visibility: hidden;`是神馬東東,我來解釋一下,因為咱們是 *3d* 的,所以其實前后兩個面咱們是能看見的,相當于咱們擁有了透視眼,而`-webkit-backface-visibility: hidden;`則是讓我們的眼鏡只能看見正最著我的圖片,而排在這圖片后面的,與他面積相等,或者比他面積小的,統(tǒng)統(tǒng)都不可見了。所以,當第二章?lián)淇伺品^來的時候,咱們是瞅不見第一張撲克牌的。
####結束
好了,以上就是我的關于六面體旋轉和紙牌翻轉的思路,有木有覺得頓時明白了呢。。。嘿嘿。在這里,十分感謝小蟲巨蟹對我的幫助和指導。也請大家多多關注菲麥前端~~~~~
另附上我的demo展示:[CSS3六面體旋轉](https://swallow-liu.github.io/Task/taskThree.html) [紙牌翻轉效果](https://swallow-liu.github.io/Task/taskTransform.html)