一、序
博主最近這些天,突發奇想的想研究一下CSS3的東西,從而提升一下CSS的能力,在學習的過程中發現其實CSS3是一個挺復雜的東西,深入的研究,你可能會涉及到初中的光學理論來幫助理解一些概念,同時如matrix可能還需要你用大學學習的矩陣來進行分析,因為這是本系列的第一篇文章,所以就從最好玩的開始介紹起,這樣也不至於讓大家失去了閱讀下去的興趣,同時寫這些文章的一個主要的原因是,CSS3挺復雜的,一方面整理一下自己的研究,方便日后重新的翻看,另一方面,也想幫助更多的讀者而來進入CSS3這個世界,提高讀者們的見識,不要像博主以前一樣,以為會了幾個標簽就好像CSS3的東西都會了一樣。
二、3D基礎概念理解
如果要說是3D的基礎概念,那么有一些屬性的理解是一定繞不過去的,首先我們就來談一談rotateX()、rotateY()、rotateZ()這幾個屬性
rotateX()、rotateY()、rotateZ()
rotateX():對應的是3D模型中的X軸上的旋轉,傳入的參數如:rotateX(45deg)表示的是頁面繞X軸順時針旋轉45度
rotateX():對應的是3D模型中的Y軸上的旋轉,傳入的參數如:rotateY(45deg)表示的是頁面繞Y軸順時針旋轉45度
rotateX():對應的是3D模型中的Z軸上的旋轉,傳入的參數如:rotateZ(45deg)表示的是頁面繞Z軸順時針旋轉45度
對應的模型如下:
注:以上模型圖的視角是+Z軸指向讀者的方向
說到這里還需要注意這幾個問題,就是頁面(圖中的菱形表示的就是頁面)與坐標軸的位置是相對位置,不是絕對位置,也就是說頁面位置一改變,坐標軸的位置也隨着頁面一起改變,這個你現在可能還不是很理解這個說法的作用,但是不用着急,如果弄個例子的話,例子會涉及到另外的一個屬性的使用,所以先在這里買一個關子。二、旋轉到與視線對其的方向的時候會出現消失的現象
HTML代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Demo1</title> </head> <style type="text/css"> #test{ height:200px; width:200px; position:absolute; margin-top:100px; margin-left:100px; } #test div{ height:200px; width:200px; background:lightblue; -webkit-transition: all .6s; } #test div:hover{ -webkit-transform:rotateX(90deg); } </style> <body> <div id="test"> <div></div> </div> </body> </html>
效果展示:
看到了沒有,這個出現空白是因為,當與你的視線是平行的時候,因為平面是沒有厚度的所以你看到的就是空白
旋轉方面的屬性我們已經講解了,接下來我們就來講解一下,3D平移的屬性,3D的平移屬性分別有:translateX()、tanslateY()、tanslateZ()這三個方法
分別就是對應的是X、Y、Z軸方向上面的平移,這個具體參照上面的坐標圖,很容易理解的,這個就不必在此多此一舉了,以translateX()為例來講解一下使用方法,如果是要使平面在X軸正方向上面移動45像素,這個時候可以這樣寫 translateX(45px),其他的使用方法一樣,接下來就結合一下上面所提到的一個坐標軸的相對位置問題來接一個例子,也作為translate這一系列屬性的一個DEMO
HTML代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Demo1</title> </head> <style type="text/css"> #test{ height:200px; width:200px; position:absolute; margin-top:100px; margin-left:100px; } #test #div2{ height:200px; width:200px; background:lightcoral; -webkit-transition: all .6s; position:relative; -webkit-transform:rotateX(-80deg) translateZ(200px); } #test:hover #div2{ -webkit-transform: rotateX(80deg); } </style> <body> <div id="test"> <div id="div2"></div> </div> </body> </html>
效果展示:
由於id=test定義的是margin-left等於margin-top的,但是由於div2中進行了移動的操作,造成了初始化頁面紅色矩形的margin-top>margin-left,但是細心的你有沒有發現,參照上圖的3D坐標軸,要使平移的應該是設置rotateY()才對,怎樣這里是用過設置rotateZ()來實現的,哈哈,想看結果的請看下面分析
其實我們可以這樣分析:
圖像中應用了rotateX(-90deg)——也就是說明了圖像目前是與我們的視線是平行的,從3D圖中我們可以看出,Z軸總是與頁面的關系是垂直關系,所以這個時候的Z軸就變成了變換之前的Y軸,所以變換后我們直接操作Z軸就可以起到操作Y軸的作用
三、3D知識點進階
看到這里我默認讀者都已經理解了上面的基礎知識點了,畢竟上面的知識點還算是比較好上手的,接下來就是3D屬性中一些比較難以理解的屬性的講解,這里會使用通俗的說法來進行說明、闡述觀點,如有錯誤,希望各位同行指出
1、perspective
這個屬性具體要怎樣描述請自行百度,但是根據我個人對這個屬性的理解,這個屬性的功能就有點像把平行光設置為聚焦光一樣,具體請看下圖的分析
注:圖片比較難找,大家將就一下
從圖中我們可以知道這個屬性相當於將默認的平行光置換成焦點光,如果是像perspective:200px,這個我們可以認為是光源離物體的距離是200px,這個數值如果是越大的話,那么等一下的物體呈現就會越小,就如圖中來講,如果是設置為200px會比設置為300px所呈現的書本的大小會更大些,但是如果是物體的Z軸(假設這個時候的物體沒有旋轉過)的數值大於大於焦點的距離,打個比方就是假設perspective:200px .math_book{-webkit-transform:translateZ(300px)},這個時候就會出現math_book在光源的后面,也就是光源沒有覆蓋到的地方,這個時候你是在頁面中什么效果都沒有呈現的,
這個時候不知道各位看官們還能不能理解這段話的意思呢!不懂沒有關系,下面通過一個示例來分析一下光源理論是怎樣得出來的
HTML代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Demo1</title> </head> <style type="text/css"> #test{ width:400px; height:400px; position:absolute; margin-left:100px; margin-top: 100px; /* 光源設置為離頁面200像素的位置 */ perspective:200px; } #test1{ width:400px; height:400px; position:relative; /* 相當於指定一個3D的空間 */ transform-style:preserve-3d; } #div2{ width:400px; height:400px; position:relative; background:lightcoral; /* 指定變換效果,變換時間為1S */ -webkit-transition: all 1s; } #test #test1:hover #div2{ /* 繞Y軸旋轉180度 */ -webkit-transform: rotateY(180deg); } </style> <body> <div id="test"> <div id="test1"> <div id="div2"></div> </div> </div> </body> </html>
效果展示
注:圖片有點大,但是也是沒有辦法的
這個案例中有幾點在這里要說明,不知道大家知不知道為什么會出現旋轉的好像要與屏幕相撞的原因?其實這個是博主故意這樣做得,我在上面的例子中把光源的位置設置為200px但是我們從設置可以知道矩形的寬是400px,旋轉的Y軸位置默認的是與Y軸平行,並且穿過中心點,所以我們也就知道了這個旋轉半圓的半徑是200px,所以這樣就導致了光源點與矩形在矩形旋轉到90度的時候相碰撞,所以這個時候,我們可以將光源點的位置設置的更遠一些,比如說是500px或者是更大,但是這個時候我們應該要注意一點就是,如果設置過大的話,會導致圖形在頁面中的呈現變小了
對了,我還沒有說明我的光源理論來的,不好意思,下面就來聊聊我自己的光源理論(理論是博主自己的心得來的,有錯希望各位大神指出),上圖
已知手電筒是發散的光源(即非平行光),如果這個時候有一個物體(圖中對應的是BOOK)繞着Y軸在旋轉,,那么我們假設在這本書的后面有一面牆,那么牆最后呈現的效果是出現了一個菱形,這個與我們看到的GIF圖像在每幀位置上面相對應。實際上,上面的圖像說到底也就是菱形的變換然后套接一個animate。如果是沒有設置perspective屬性,那么就會出現我說所的平行光的效果,平行光效果,請看下圖
相信大家都看出來是什么效果吧,就是平行光效果就是說:如果是平行光照射到物體上面,即使物體繞着Y軸旋轉,那么最后在頁面上呈現的效果也是一個矩形邊框的變
perspective屬性就說到這里了,在上面的例子中我們還提到了另外的一個屬性就是 transform-style:preserve-3d;這個屬性其實就相當於創建一個3D的空間
我們這里就來假設一下,假設perspective對應的是發散光源,transform-style對應的是一個舞台,如果舞台是一個2維的也就是像電視一樣的,那么這樣最后也產生不來一個3D的效果,但是如果舞台是一個3D,例如舞台是一個京劇舞台,那么這個3D的舞台投影上就可以看到3維的變化,所以我們急需要perspective屬性來設置"光源"類型,也需要transform-style來設置一個投影的3D空間.
在使用perspective的時候我們需要注意的是如果把這個屬性加在某些具體元素上面並且旋轉的角度相同,那么這些元素所呈現的效果是相同的,這個正好可以用perspective類比為光源來解釋,如果在每個對象上面加上個一個光源,那么投影就是一樣的,但是如果是加在這些元素的父節點上面,那么元素所呈現的效果是不同的,這個的解釋是我們把光源加在這些元素上面,那么我們可以把這些元素看成是一個這些元素都在一個平面上面,那么因為因為光源的位置是一定的,但是每個元素在平面上面的位置不一樣,所以呈現的就是不同的效果(這個可能比較抽象難以理解,如果有疑問的話可以在后面留言)
perspective-orgin:這個屬性相當於是設置坐標的原點,因為默認的原點是在圖像的中心位置,但是有時候我們可能像旋轉的中心的位置變換一下,這個時候,這個屬性就可以滿足我們的需求
backface-visibility:這個屬性是用來設置3D的背景是不是透明的,選項有visible|hidden,默認的是hidden
如果還是有不太明白的話,具體可以參照張鑫旭的好吧,CSS3 3D transform變換,不過如此!看完之后再來看這篇文章可能會對你的理解上有一個提升幫助
四、案例練習
先來看一下效果:
看起來很炫是不是,這個其實的制作原理就是按照我在上面提到的這些屬性去制作的,首先我們分析一下,在創建這個的時候,第一步我們要引入光源,然后是添加一個3D的舞台,接着是把帶猴子的圖片放在垃圾桶圖片的下面並且邊緣相接,最后在這些圖片的父類定義一個動畫,就是在鼠標懸停的時候出發的動作,這樣這個就制作完成了,對了在這個例子中圖片的尺寸最好要相同(里面這些圖是博主在網上找的)
具體的HTML代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CSS3練習案例</title> </head> <style type="text/css"> *{ margin:0px; padding:0px; } .light{ margin-top:200px; margin-left: 200px; width:310px; height:100px; position:absolute; perspective:500px; } .light .stage{ position:relative; width:310px; height:100px; transform-style:preserve-3d; -webkit-transition: all 0.8s; } .light .stage .image1{ width:310px; height:100px; position:absolute; -webkit-transform:translateZ(50px) ; -webkit-transition: all 0.8s; } .light .stage .image2{ width:310px; height:100px; position:absolute; -webkit-transition: all 0.8s; -webkit-transform: rotateX(-90deg) translateZ(50px); } .light .stage:hover{ -webkit-transform: rotateX(90deg); } </style> <body> <div class="light"> <div class="stage"> <img class="image1" src="images/a.png" /> <img class="image2" src="images/b.jpeg" /> </div> </div> </body> </html>
圖片我就不提供了,請自行百度上找
五、總結
這節我們梳理了CSS3中3D效果制作的一些標簽以及通過一個小小的案例來分析標簽是怎樣使用的,如果有那個地方是由說錯的,希望各位不吝筆墨,告訴我一聲,謝謝