要玩轉css3的3d,就必須瞭解幾個辭彙,便是透視(perspective)、旋轉(rotate)和移動(translate)。透視即是以現實的視角來看屏幕上的2D事物,從而展現3D的效果。旋轉則不再是2D平面上的旋轉,而是三維坐標系的旋轉,就包括X軸,Y軸,Z軸旋轉。平移同理。 當然用理論來說明, ...
要玩轉css3的3d,就必須瞭解幾個辭彙,便是透視(perspective
)、旋轉(rotate
)和移動(translate
)。透視
即是以現實的視角來看屏幕上的2D事物,從而展現3D的效果。旋轉
則不再是2D平面上的旋轉,而是三維坐標系的旋轉,就包括X軸,Y軸,Z軸旋轉。平移
同理。
當然用理論來說明,估計你還不明白。下麵是3個gif:
- 沿著X軸旋轉
- 沿著Y軸旋轉
- 沿著Z軸旋轉
旋轉應該沒問題了,那理解平移起來就比較容易了,就是在在X軸、Y軸、z軸移動。
你可能會說透視比較不好理解,下麵我介紹一下透視的幾個屬性。
perspective
perspective
英文名便是透視,沒有這東西就沒辦法形成3D效果,但是這個東西是怎麼讓我們瀏覽器形成3D 效果的呢,可以看下麵這張圖,其實學過繪畫的應該知道透視關係,而這裡就是這個道理。
但是在css里它是有數值的,例如perspective: 1000px
這個代表什麼呢?我們可以這樣理解,如果我們直接眼睛靠著物體看,物體就超大占滿我們的視線,我們離它距離越來越大,它在變小,立體感也就出來了是不是,其實這個數值構造了一個我們眼睛離屏幕的距離,也就構造了一個虛擬3D假象。
perspective-origin
由上面我們瞭解了perspective
,而加上了這個origin
是什麼,我們前面說的這個是眼睛離物體的距離,而這個就是眼睛的視線,我們的視點的不同位置就決定了我們看到的不同景象,預設是中心,為perspectice-origin: 50% 50%
,第一個數值是 3D 元素所基於的 X 軸,第二個定義在 y 軸上的位置
當為元素定義 perspective-origin 屬性時,其子元素會獲得透視效果,而不是元素本身。必須與 perspective 屬性一同使用,而且隻影響 3D 轉換元素。(W3school)
transform-style
perspective又來了,沒錯,它是css中3D的關鍵,transform-style
預設是flat
,如果你要在元素上視線3D效果的話,就必須用上transform-style: preserve-3d
,否則就只是平面的變換,而不是3D的變換
手把手帶你玩轉css3-3d
以上我們稍微瞭解概念,下麵就開始實戰吧!
我們看一個效果,是不是很酷炫~
如果圖片載入不出來,就直接訪問線上預覽,覺得可以的話記得給star咯hh
第一步:html結構
很簡單的一個容器包裹著一個裝了6個piece
的piece-box
< div class = "container" >
< div class = "piece-box" >
< div class = "piece piece-1" ></ div >
< div class = "piece piece-2" ></ div >
< div class = "piece piece-3" ></ div >
< div class = "piece piece-4" ></ div >
< div class = "piece piece-5" ></ div >
< div class = "piece piece-6" ></ div >
</ div >
</ div >
|
第二步: 加上必要的3D屬性,進入3D世界
通過上面的講解,應該對perspective
比較熟悉了吧,
/*容器*/
.container {
-webkit-perspective: 1000px ;
-moz-perspective: 1000px ;
-ms-perspective: 1000px ;
perspective: 1000px ;
}
/*piece盒子*/
.piece-box {
perspective-origin: 50% 50% ;
-webkit-transform-style: preserve -3 d;
-moz-transform-style: preserve -3 d;
-ms-transform-style: preserve -3 d;
transform-style: preserve -3 d;
}
|
第三步:加入必要的樣式
/*容器*/
.container {
-webkit-perspective: 1000px ;
-moz-perspective: 1000px ;
-ms-perspective: 1000px ;
perspective: 1000px ;
}
/*piece盒子*/
.piece-box {
position : relative ;
width : 200px ;
height : 200px ;
margin : 300px auto ;
perspective-origin: 50% 50% ;
-webkit-transform-style: preserve -3 d;
-moz-transform-style: preserve -3 d;
-ms-transform-style: preserve -3 d;
transform-style: preserve -3 d;
}
/*piece通用樣式*/
.piece {
position : absolute ;
width : 200px ;
height : 200px ;
background : red ;
opacity: 0.5 ;
}
.piece -1 {
background : #FF6666 ;
}
.piece -2 {
background : #FFFF00 ;
}
.piece -3 {
background : #006699 ;
}
.piece -4 {
background : #009999 ;
}
.piece -5 {
background : #FF0033 ;
}
.piece -6 {
background : #FF6600 ;
}
|
當然,在你完成這步之後你還是只看到一個正方形,也就是我們的piece-6
,因為我們的3Dtransform
還沒開始
第四步:3D變換來襲
首先是實現走馬燈,我們先不要讓它走,先實現燈部分。
如何實現呢?因為要構成一個圓,圓是360度,而我們有6個piece,那麼,很容易想到,我們需要把每一個piece以遞增60度的方式rotateY
,就變成如下
如何把他們從中心拉開呢?
這裡我們還要註意一點,在我們使元素繞Y軸旋轉以後,其實X軸和Z軸也會跟著旋轉,所所以正方體的每個面的垂直線還是Z軸,我們就只需要改變下
translateZ
的值,而當translateZ
為正的時候,就朝著我們的方向走來,這樣就可以拉開了
但是拉開的距離如何衡量?
是不是一目瞭然了~
下麵我們再修改下css
.piece -1 {
background : #FF6666 ;
-webkit-transform: rotateY( 0 deg) translateZ( 173.2px );
-ms-transform: rotateY( 0 deg) translateZ( 173.2px );
-o-transform: rotateY( 0 deg) translateZ( 173.2px );
transform: rotateY( 0 deg) translateZ( 173.2px );
}
.piece -2 {
background : #FFFF00 ;
-webkit-transform: rotateY( 60 deg) translateZ( 173.2px );
-ms-transform: rotateY( 60 deg) translateZ( 173.2px );
-o-transform: rotateY( 60 deg) translateZ( 173.2px );
transform: rotateY( 60 deg) translateZ( 173.2px );
}
.piece -3 {
background : #006699 ;
-webkit-transform: rotateY( 120 deg) translateZ( 173.2px );
-ms-transform: rotateY( 120 deg) translateZ( 173.2px );
-o-transform: rotateY( 120 deg) translateZ( 173.2px );
transform: rotateY( 120 deg) translateZ( 173.2px );
}
.piece -4 {
background : #009999 ;
-webkit-transform: rotateY( 180 deg) translateZ( 173.2px );
-ms-transform: rotateY( 180 deg) translateZ( 173.2px );
-o-transform: rotateY( 180 deg) translateZ( 173.2px );
transform: rotateY( 180 deg) translateZ( 173.2px );
}
.piece -5 {
background : #FF0033 ;
-webkit-transform: rotateY( 240 deg) translateZ( 173.2px );
-ms-transform: rotateY( 240 deg) translateZ( 173.2px );
-o-transform: rotateY( 240 deg) translateZ( 173.2px );
transform: rotateY( 240 deg) translateZ( 173.2px );
}
.piece -6 {
background : #FF6600 ;
-webkit-transform: rotateY( 300 deg) translateZ( 173.2px );
-ms-transform: rotateY( 300 deg) translateZ( 173.2px );
-o-transform: rotateY( 300 deg) translateZ( 173.2px );
transform: rotateY( 300 deg) translateZ( 173.2px );
}
|
是不是已經實現了走馬燈了?
第五步:animation讓3D動起來
要實現走馬燈動,其實很簡單,我們只要在piece-box
上加上旋轉動畫就行了,5s完成動畫,從0度旋轉到360度
/*piece盒子*/
.piece-box {
position : relative ;
width : 200px ;
height : 200px ;
margin : 300px auto ;
perspective-origin: 50% 50% ;
-webkit-transform-style: preserve -3 d;
-moz-transform-style: preserve -3 d;
-ms-transform-style: preserve -3 d;
transform-style: preserve -3 d;
animation: pieceRotate 5 s;
-moz-animation: pieceRotate 5 s; /* Firefox */
-webkit-animation: pieceRotate 5 s; /* Safari and Chrome */
-o-animation: pieceRotate 5 s ; /* Opera */
}
/*走馬燈動畫*/
@keyframes pieceRotate
{
0% {-webkit-transform: rotateY( 0 deg);
-ms-transform: rotateY( 0 deg);
-o-transform: rotateY( 0 deg);
transform: rotateY( 0 deg);}
100% {-webkit-transform: rotateY( 360 deg);
-ms-transform: rotateY( 360 deg);
-o-transform: rotateY( 360 deg);
transform: rotateY( 360 deg);}
}
/* Firefox */
@-moz-keyframes pieceRotate
{
0% {-webkit-transform: rotateY( 0 deg);
-ms-transform: rotateY( 0 deg);
-o-transform: rotateY( 0 deg);
transform: rotateY( 0 deg);}
100% {-webkit-transform: rotateY( 360 deg);
-ms-transform: rotateY( 360 deg);
-o-transform: rotateY( 360 deg);
transform: rotateY( 360 deg);}
}
/* Safari and Chrome */
@-webkit-keyframes pieceRotate
{
0% {-webkit-transform: rotateY( 0 deg);
-ms-transform: rotateY( 0 deg);
-o-transform: rotateY( 0 deg);
transform: rotateY( 0 deg);}
100% {-webkit-transform: rotateY( 360 deg);
-ms-transform: rotateY( 360 deg);
-o-transform: rotateY( 360 deg);
transform: rotateY( 360 deg);}
}
/* Opera */
@-o-keyframes pieceRotate
{
0% {-webkit-transform: rotateY( 0 deg);
-ms-transform: rotateY( 0 deg);
-o-transform: rotateY( 0 deg);
transform: rotateY( 0 deg);}
100% {-webkit-transform: rotateY( 360 deg);
-ms-transform: rotateY( 360 deg);
-o-transform: rotateY( 360 deg);
transform: rotateY( 360 deg);}
}
|
這裡就不放gif了~hhh是不是實現了酷炫的效果,還沒結束哦~更酷炫的正方體組裝
正方體,其實也不難實現,我這裡就不很詳細說了,你首先可以想象一個面,然後去拓展其他面如何去實現,比如我們把正方體的前面
translateZ(100px)
讓它靠近我們100px,然後後面translateZ(-100px)
讓它遠離我們100px,左邊是先translateX(-100px
再rotateY(90deg)
,右邊就是translateX(100px)
再rotateY(90deg)
,上面是先translateY(-100px)
,rotateX(90deg)
,下麵是先translateY(100px)
,rotateX(90deg)
,只要我們寫進動畫,一切就大功告成。
css就為如下,以下就只放piece1
,其他讀者可以自己類比實現,或者看我github的源碼
.piece -1 {
background : #FF6666 ;
-webkit-transform: rotateY( 0 deg) translateZ( 173.2px );
-ms-transform: rotateY( 0 deg) translateZ( 173.2px );
-o-transform: rotateY( 0 deg) translateZ( 173.2px );
transform: rotateY( 0 deg) translateZ( 173.2px );
animation: piece 1 Rotate 5 s 5 s;
-moz-animation: piece 1 Rotate 5 s 5 s; /* Firefox */
-webkit-animation: piece 1 Rotate 5 s 5 s; /* Safari and Chrome */
-o-animation: piece 1 Rotate 5 s 5 s; /* Opera */
-webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
animation-fill-mode: forwards;
}
/*front*/
@keyframes piece 1 Rotate
{
0% {-webkit-transform: rotateY( 0 deg) translateZ( 173.2px );
-ms-transform: rotateY( 0 deg) translateZ( 173.2px );
-o-transform: rotateY( 0 deg) translateZ( 173.2px );
transform: rotateY( 0 deg) translateZ( 173.2px );}
100% {-webkit-transform: rotateY( 0 deg) translateZ( 100px );
-ms-transform: rotateY( 0 deg) translateZ( 100px );
-o-transform: rotateY( 0 deg) translateZ( 100px );
transform: rotateY( 0 deg) translateZ( 100px );}
}
/* Firefox */
@-moz-keyframes piece 1 Rotate
{
0% {-webkit-transform: rotateY( 0 deg) translateZ( 173.2px );
-ms-transform: rotateY( 0 deg) translateZ( 173.2px );
-o-transform: rotateY( 0 deg) translateZ( 173.2px );
transform: rotateY( 0 deg) translateZ( 173.2px );}
100% {-webkit-transform: rotateY( 0 deg) translateZ( 100px );
-ms-transform: rotateY( 0 deg) translateZ( 100px );
-o-transform: rotateY( 0 deg) translateZ( 100px );
transform: rotateY( 0 deg) translateZ( 100px );}
}
/* Safari and Chrome */
@-webkit-keyframes piece 1 Rotate
{
0% {-webkit-transform: rotateY( 0 deg) translateZ( 173.2px );
-ms-transform: rotateY( 0 deg) translateZ( 173.2px );
-o-transform: rotateY( 0 deg) translateZ( 173.2px );
transform: rotateY( 0 deg) translateZ( 173.2px );}
100% {-webkit-transform: rotateY( 0 deg) translateZ( 100px );
-ms-transform: rotateY( 0 deg) translateZ( 100px );
-o-transform: rotateY( 0 deg) translateZ( 100px );
transform: rotateY( 0 deg) translateZ( 100px );}
}
/* Opera */
@-o-keyframes piece 1 Rotate
{
0% {-webkit-transform: rotateY( 0 deg) translateZ( 173.2px );
-ms-transform: rotateY( 0 deg) translateZ( 173.2px );
-o-transform: rotateY( 0 deg) translateZ( 173.2px );
transform: rotateY( 0 deg) translateZ( 173.2px );}
100% {-webkit-transform: rotateY( 0 deg) translateZ( 100px );
-ms-transform: rotateY( 0 deg) translateZ( 100px );
-o-transform: rotateY( 0 deg) translateZ( 100px );
transform: rotateY( 0 deg) translateZ( 100px );}
}
|
細心的讀者可以發現我用了一個
animation-fill-mode: forwards;
,這個其實就是讓這些piece
保持動畫最後的效果,也就是正方體的效果,讀者可以不加試試看,那還是會恢複原樣。
最後就是正方體的旋轉了,前面我們的容器已經用過animation
了,讀者可能會想我再加個class放animaiton
不就行了,hhh,animaiton
會覆蓋掉前面的,那前面的走馬燈的動畫就沒了,所以在html結構中,我再加了一個box
包裹piece
, 如下