以前學習 react+webpack ,偶然路過 webpack 官網 ,看到頂部的 LOGO ,就很感興趣。javascript
最近以爲本身 CSS3 過於薄弱,想着深刻學習一番,遂以這個 LOGO 爲切入口,好好研究學習了一下相關的 CSS3 屬性。webpack 的 LOGO 動畫效果乍看不是很難,深刻了解以後,以爲內部其實大有學問,本身折騰了一番,作了一系列相關的 CSS3 動畫效果。css
先上 demo ,沒有將精力放在兼容上,請用 chrome 打開。html
本文完整的代碼,以及更多的 CSS3 效果,在我 github 上能夠看到,也但願你們能夠點個 star。前端
嗯,可能有些人打不開 demo 或者頁面亂了,貼幾張效果圖:(圖片有點大,耐心等待一會)java
可能上面的效果對精通 CSS3 的而言小菜一碟,寫本文的目的也是我本身學習積累的一個過程,感興趣的就能夠一塊兒往下看啦。react
其實 CSS3 效果然的很強大,上面的效果都是純 CSS 實現,我的感受越是深刻 CSS 的學習,越是以爲本身不懂 CSS ,不過話說回來,這些效果的實用場景不大,可是做爲一個有追求的前端,我以爲仍是有必要去好好了解一下這些屬性。webpack
因此本文接下來要講的大概有:css3
要利用 CSS3 實現 3D 的效果,最主要的就是藉助 transform-style 屬性。transform-style 只有兩個值能夠選擇:git
// 語法: transform-style: flat|preserve-3d; transform-style: flat; // 默認,子元素將不保留其 3D 位置 transform-style: preserve-3d; // 子元素將保留其 3D 位置。
當咱們指定一個容器的 transform-style 的屬性值爲 preserve-3d 時,容器的後代元素便會具備 3D 效果,這樣說有點抽象,也就是當前父容器設置了 preserve-3d 值後,它的子元素就能夠相對於父元素所在的平面,進行 3D 變形操做。github
當父元素設置了 transform-style:preserve-3d 後,就能夠對子元素進行 3D 變形操做了,3D 變形和 2D 變形同樣能夠,使用 transform 屬性來設置,或者能夠經過制定的函數或者經過三維矩陣來對元素變型操做:
一、使用 translateX(length) 、translateY(length) 、 translateZ(length) 來進行 3D 位移操做,與 2D 操做同樣,對元素進行位移操做,也能夠合併爲 translate3d(x,y,z) 這種寫法;
二、使用 scaleX() 、scaleY() 、scaleY() 來進行3D 縮放操做,也能夠合併爲 scale3d(number,number,number) 這種寫法;
三、使用 rotateX(angle) 、rotateY(angle) 、rotateZ(angle) 來進行 3D 旋轉操做,也能夠合併爲 rotate3d(Xangle,Yangle,Zangle) 這種寫法。
對於 API 的學習,我建議去源頭看看,不要知足於消費別人的總結,transform-style API。
這裏要特別提出的,3D 座標軸,所謂的繞 X、Y、Z 軸的三個軸,這個不難,感受空間想象困難的,照着 API 試試,繞每一個軸都轉一下就明白了:
瞭解事後,那麼依靠上面所說的,其實咱們就已經能夠作一個立方體出來了。所謂實踐出真知,下面就看看該如何一步步獲得一個立方體。
一、準備六個正方形
這個好理解,正方體六個面,首先用 div 作出 6 個面,包裹在同一個父級容器下面,父級容器設置 transform-style:preserve-3d ,這樣接下來就能夠對 6 個面進行 3D 變換操做,爲了方便演示,我用 6 個顏色不同的面:
上面的圖是示意有 6 個面,固然咱們要把 6 個正方形 div 設置爲絕對定位,重疊疊在一塊兒,那麼應該是這樣的,只能看到一個面:
二、父容器作簡單的變換
爲了最後的看上去的效果好看,咱們須要先對父容器進行變換,運用上面說的 rotate 屬性,將容器的角度改變一下:
.cube-container{ -webkit-transform: rotateX(-33.5deg) rotateY(45deg); transform: rotateX(-33.5deg) rotateY(45deg); }
那麼,變換以後,獲得這樣一個圖形:
嗯,這個時候,6 個 div 面仍然是重疊在一塊兒的。
三、對每一個面作 3D 變換
接下來就是對每一個面進行 3D 變換了,運用 rotate 能夠對 div 平面進行旋轉,運用 translate 能夠對 div 平面進行平移,並且要記住如今咱們是在三維空間內變換,轉啊轉啊,咱們可能會獲得這樣的形狀:
算好旋轉角度和偏移距離,最後上面的 6 個面就能夠完美拼成一個立方體咯!爲了效果更好,我給每一個面增長一些透明度,最後獲得一個完整的立方體:
爲了更有立體感,咱們能夠調整父容器的旋轉角度,旋轉看上去更立體的角度:
至此,一個 3D 立方體就完成了。寫這篇文章的時候,原本到這裏,這一塊應該就結束了,可是寫到這裏的時候,忽然突發奇想,既然正方體能夠(正六面體),那麼正四面體,正八面體甚至球體應該也能作出來吧?
嗯,沒有按住躁動的心,立馬動手嘗試了一番,最後作出了下面的兩個:
就再也不詳細討論如何一步一步獲得這兩個了,有興趣的能夠去個人 github 上看看源碼,或者直接和我討論交流,簡單的談談思路:
和正方體同樣,咱們首先要準備 4 個三角形(下面會詳細講如何利用 CSS3 製做一個三角形 div),注意 4 個三角形應該是重疊在一塊兒的,而後將其中三個分別沿着三條邊的中心點旋轉 70.5 度(正四面體臨面夾角),就能夠獲得一個正四面體。
注意沿着三條邊的中心點旋轉 70.5 度這句話,意思是每一個圖形要定位一次旋轉中心,也就是 transform-origin 屬性,它容許咱們設置旋轉元素的基點位置。
上面的 GIF 圖由於添加了 animation 動畫效果,看上去很像一個球體在運動,其實只用了 4 個 div,每一個 div 利用 border-radius:100% 設置爲圓形,而後以中心點爲基準,每一個圓形 div 繞 Y 軸旋轉不一樣的角度,再讓整個圓形容器繞 Y 軸動起來,就能夠獲得這樣一個效果了。
繼續說 3D ,接下來要說的屬性是 persepective 和 perspective-origin 。
// 語法 perspective: number|none;
perspective 爲一個元素設置三維透視的距離,僅做用於元素的後代,而不是其元素自己。
簡單來講,當元素沒有設置 perspective 時,也就是當 perspective:none/0 時全部後代元素被壓縮在同一個二維平面上,不存在景深的效果。
而若是設置 perspective 後,將會看到三維的效果。
perspective-origin 表示 3D 元素透視視角的基點位置,默認的透視視角中心在容器是 perspective 所在的元素,而不是他的後代元素的中點,也就是 perspective-origin: 50% 50%。
// 語法 perspective-origin: x-axis y-axis; // x-axis : 定義該視圖在 x 軸上的位置。默認值:50% // y-axis : 定義該視圖在 y 軸上的位置。默認值:50%
值得注意的是,CSS3 3D 變換中的透視的透視點是在瀏覽器的前方。
說老是很難理解,運用上面咱們作出來的正方體試驗一下,我設置了正方體的邊長爲 50 px ,這裏設置正方體容器 cuber-inner 的 persepective 的爲 100 px,而 perspective-origin 保持爲默認值:
-webkit-perspective-origin: 50% 50%; perspective-origin: 50% 50%; -webkit-perspective: 100px; perspective: 100px;
上面這樣設置,也就是至關於我站在 100px 的長度外去看這個立方體,效果以下:
經過調整 persepective 和 perspective-origin 的值,能夠看到不同的圖形,這個很好理解,咱們觀測一個物體的角度和距離物體的距離不斷髮生改變,咱們看的物體也是不同的,嗯想象一下小學課文,楊桃和星星,就能容易明白了。
須要提出的是,我上面的幾個正多面體圖形和球形圖形是沒有加上 persepective 值的,感興趣的能夠加上試一下看看效果。
回到文章一開始我貼的那個 3D 照片牆,運用 transform-style: preserve-3d 和 persepective ,能夠作出效果很好的這種 3D 照片牆旋轉效果。
代碼就不貼了,本文已經很長了,只是簡單的談談原理,感興趣的去扒源碼看看。
一、設立一個舞臺,也就是包裹旋轉的圖片們的容器,給他設置一個 persepective 距離,以及 transform-style: preserve-3d 讓後代能夠進行 3D 變換;
二、準備 N 張圖片置於容器內部,N 的大小看我的喜愛了,圖片的 3D 旋轉木馬效果是相似鋼管舞旋轉的運動,所以是繞 Y 軸的,咱們關心的是 rotateY 的大小,根據咱們添加的圖片數量,用 360° 的圓周角將每一個圖片等分,也就是讓每張圖片繞 Y 軸旋轉固定角度依次散開:(下面的圖爲示意效果,我調整了一下角度和透明度)
三、這個時候,N 張圖確定是重合疊在了一塊兒,因此這裏關鍵一步是運用 translateZ(length) 讓圖片沿 Z 軸平移,也就是運用 translateZ 可讓圖片離咱們更近或者更遠,由於上一步設置了圖片不一樣的 rotateY() 角度,因此 N 張圖片設定一個 translateZ 後,圖片就很天然以中點爲圓心分散開了,也就是這樣:
四、最後利用 animation ,咱們讓舞臺,也就是包裹着圖片的容器繞 Y 軸旋轉起來(rotateY),那麼一個相似旋轉木馬的 3D 照片牆效果就完成了!
這裏要注意的一點是設置的 persepective 值和單個圖片 translateZ(length) 的值,persepective 必定要比 translateZ(length) 的值大,不然就是至關於舞臺跑你身後去了,確定是看不到效果了。
原本想繼續說
這些個可讓動畫效果變得更讚的一些 CSS3 屬性,可是以爲本文篇幅已經很長,並且這兩個屬性有點偏離主題,打算另起一文,再作深刻探究。
再說兩點本文沒有談到的,可是頗有用處的小細節,感興趣的能夠去了解了解,也會在接下來進行詳細探討:
OK,本文到此結束,若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。
本文完整的代碼,以及更多的 CSS3 效果,在我 github 上能夠看到,也但願你們能夠點個 star。
本文的 demo 戳我。
若是本文對你有幫助,請點下推薦,寫文章不容易。