【CSS3進階】酷炫的3D旋轉透視

来源:http://www.cnblogs.com/coco1s/archive/2016/04/21/5414153.html
-Advertisement-
Play Games

之前學習 react+webpack ,偶然路過 webpack 官網 ,看到頂部的 LOGO ,就很感興趣。 最近覺得自己 CSS3 過於薄弱,想著深入學習一番,遂以這個 LOGO 為切入口,好好研究學習了一下相關的 CSS3 屬性。webpack 的 LOGO 動畫效果乍看不是很難,深入瞭解之後 ...


之前學習 react+webpack ,偶然路過 webpack 官網 ,看到頂部的 LOGO ,就很感興趣。

最近覺得自己 CSS3 過於薄弱,想著深入學習一番,遂以這個 LOGO 為切入口,好好研究學習了一下相關的 CSS3 屬性。webpack 的 LOGO 動畫效果乍看不是很難,深入瞭解之後,覺得內部其實大有學問,自己折騰了一番,做了一系列相關的 CSS3 動畫效果。

先上 demo ,沒有將精力放在相容上,請用 chrome 打開。

本文完整的代碼,以及更多的 CSS3 效果,在我 github 上可以看到,也希望大家可以點個 star。

嗯,可能有些人打不開 demo 或者頁面亂了,貼幾張效果圖:(圖片有點大,耐心等待一會)

立方體 3D 旋轉

3D 透視照片牆

跳躍的音符

可能上面的效果對精通 CSS3 的而言小菜一碟,寫本文的目的也是我自己學習積累的一個過程,感興趣的就可以一起往下看啦。

其實 CSS3 效果真的很強大,上面的效果都是純 CSS 實現,個人感覺越是深入 CSS 的學習,越是覺得自己不懂 CSS ,不過話說回來,這些效果的實用場景不大,但是作為一個有追求的前端,我覺得還是有必要去好好瞭解一下這些屬性。

所以本文接下來要講的大概有:

  • transform-style: preserve-3d 三維效果
  • perspective and perspective-origin 3D視距,透視/景深效果
  • CSS3 filter CSS3濾鏡
  • transparent、radial-gradient 透明與漸變

   

   transform-style

要利用 CSS3 實現 3D 的效果,最主要的就是藉助 transform-style 屬性。transform-style 只有兩個值可以選擇:

// 語法:
transform-style: flat|preserve-3d;

transform-style: flat; // 預設,子元素將不保留其 3D 位置
transform-style: preserve-3d; // 子元素將保留其 3D 位置。

當我們指定一個容器的 transform-style 的屬性值為 preserve-3d 時,容器的後代元素便會具有 3D 效果,這樣說有點抽象,也就是當前父容器設置了 preserve-3d 值後,它的子元素就可以相對於父元素所在的平面,進行 3D 變形操作。

當父元素設置了 transform-style:preserve-3d 後,就可以對子元素進行 3D 變形操作了,3D 變形和 2D 變形一樣可以,使用 transform 屬性來設置,或者可以通過制定的函數或者通過三維矩陣來對元素變型操作:

1、使用 translateX(length) 、translateY(length) 、 translateZ(length) 來進行 3D 位移操作,與 2D 操作一樣,對元素進行位移操作,也可以合併為 translate3d(x,y,z) 這種寫法;

2、使用 scaleX() 、scaleY() 、scaleY() 來進行3D 縮放操作,也可以合併為 scale3d(number,number,number) 這種寫法;

3、使用 rotateX(angle) 、rotateY(angle) 、rotateZ(angle) 來進行 3D 旋轉操作,也可以合併為 rotate3d(Xangle,Yangle,Zangle) 這種寫法。

對於 API 的學習,我建議去源頭看看,不要滿足於消費別人的總結,transform-style API

這裡要特別提出的,3D 坐標軸,所謂的繞 X、Y、Z 軸的三個軸,這個不難,感覺空間想象困難的,照著 API 試試,繞每個軸都轉一下就明白了:

 瞭解過後,那麼依靠上面所說的,其實我們就已經可以做一個立方體出來了。所謂實踐出真知,下麵就看看該如何一步步得到一個立方體。

 1、準備六個正方形

這個好理解,正方體六個面,首先用 div 做出 6 個面,包裹在同一個父級容器下麵,父級容器設置 transform-style:preserve-3d ,這樣接下來就可以對 6 個面進行 3D 變換操作,為了方便演示,我用 6 個顏色不一樣的面:

上面的圖是示意有 6 個面,當然我們要把 6 個正方形 div 設置為絕對定位,重疊疊在一起,那麼應該是這樣的,只能看到一個面:

2、父容器做簡單的變換

為了最後的看上去的效果好看,我們需要先對父容器進行變換,運用上面說的 rotate 屬性,將容器的角度改變一下:

.cube-container{
    -webkit-transform: rotateX(-33.5deg) rotateY(45deg);
    transform: rotateX(-33.5deg) rotateY(45deg);
}

那麼,變換之後,得到這樣一個圖形:

嗯,這個時候,6 個 div 面仍然是重疊在一起的。

3、對每個面做 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 軸動起來,就可以得到這樣一個效果了。

 

   perspective and perspective-origin 3D視距,透視/景深效果

繼續說 3D ,接下來要說的屬性是 persepective 和 perspective-origin 。

persepective 

// 語法
perspective: number|none;

perspective 為一個元素設置三維透視的距離,僅作用於元素的後代,而不是其元素本身。

簡單來說,當元素沒有設置 perspective 時,也就是當 perspective:none/0 時所有後代元素被壓縮在同一個二維平面上,不存在景深的效果。

而如果設置 perspective 後,將會看到三維的效果。

perspective-origin

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 透視照片牆

回到文章一開始我貼的那個 3D 照片牆,運用 transform-style: preserve-3d 和 persepective ,可以做出效果很好的這種 3D 照片牆旋轉效果。

代碼就不貼了,本文已經很長了,只是簡單的談談原理,感興趣的去扒源碼看看。

1、設立一個舞臺,也就是包裹旋轉的圖片們的容器,給他設置一個 persepective 距離,以及 transform-style: preserve-3d 讓後代可以進行 3D 變換;

2、準備 N 張圖片置於容器內部,N 的大小看個人喜好了,圖片的 3D 旋轉木馬效果是類似鋼管舞旋轉的運動,因此是繞 Y 軸的,我們關心的是 rotateY 的大小,根據我們添加的圖片數量,用 360° 的圓周角將每個圖片等分,也就是讓每張圖片繞 Y 軸旋轉固定角度依次散開:(下麵的圖為示意效果,我調整了一下角度和透明度)

3、這個時候,N 張圖肯定是重合疊在了一起,所以這裡關鍵一步是運用 translateZ(length) 讓圖片沿 Z 軸平移,也就是運用 translateZ 可以讓圖片離我們更近或者更遠,因為上一步設置了圖片不同的 rotateY() 角度,所以 N 張圖片設定一個 translateZ 後,圖片就很自然以中點為圓心分散開了,也就是這樣:

 

4、最後利用 animation ,我們讓舞臺,也就是包裹著圖片的容器繞 Y 軸旋轉起來(rotateY),那麼一個類似旋轉木馬的 3D 照片牆效果就完成了!

這裡要註意的一點是設置的 persepective 值和單個圖片 translateZ(length) 的值,persepective 一定要比 translateZ(length) 的值大,否則就是相當於舞臺跑你身後去了,肯定是看不到效果了。

 

本來想繼續說

  • CSS3 filter CSS3濾鏡
  • transparent、radial-gradient 透明與漸變

這些個可以讓動畫效果變得更贊的一些 CSS3 屬性,但是覺得本文篇幅已經很長,而且這兩個屬性有點偏離主題,打算另起一文,再做深入探究。

再說兩點本文沒有談到的,但是很有用處的小細節,感興趣的可以去瞭解瞭解,也會在接下來進行詳細探討:

1、使用 transform3d api 代替 transform api,強制開啟 GPU 加速,提升網站動畫渲染性能;

2、使用 CSS3 will-change 提高頁面滾動、動畫等渲染性能

 

OK,本文到此結束,如果還有什麼疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。

本文完整的代碼,以及更多的 CSS3 效果,在我 github 上可以看到,也希望大家可以點個 star。

本文的 demo 戳我。

如果本文對你有幫助,請點下推薦,寫文章不容易。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 知道這20個正則表達式,能讓你少寫1,000行代碼 正則表達式,一個十分古老而又強大的文本處理工具,僅僅用一段非常簡短的表達式語句,便能夠快速實現一個非常複雜的業務邏輯。熟練地掌握正則表達式的話,能夠使你的開發效率得到極大的提升。 正則表達式經常被用於欄位或任意字元串的校驗,如下麵這段校驗基本日期格 ...
  • line-height這個樣式相信大家一定不會陌生,我們經常用它來讓文本上下居中,這樣做一般不出出現什麼問題,但是如果對這個屬性不是很熟悉的話,可能會踩到一些坑,今天親自去試驗了一下,並總結了一下line-height的幾個特性。 首先line-height有以下幾種標準的寫法: 寫法1、line- ...
  • 1. 定義:Promise是抽象非同步處理對象以及對其進行各種操作的組件,它把非同步處理對象和非同步處理規則採用統一的介面進行規範化。 2. ES6 Promises 標準中定義的API: a) Constructor:採用new來實例化, var promise = new Promise(functi... ...
  • 只舉例火狐和谷歌.如果是火狐,一般是用firebug,首先確保開啟腳本調試: 然後刷新一下要調試的頁面,點擊firebug中的行內,選擇當前頁面: js文件一般直接顯示的是js文件的名字,而頁面一般是攔截的請求路徑,如上圖所示請求路徑為/login,顯示的是login. 選中頁面後就可以看到頁面的代 ...
  • //<![CDATA[ //這裡放代碼 //]]> 基本類型 引用類型 動態添加屬性 不可以,不會出錯,但會出現underfined 可以 複製變數值 相互獨立 指向同一個對象,相互影響 傳遞參數(函數外部的值傳遞給函數內部) 相互獨立 指向同一個對象,相互影響,但是在函數內部重寫的值,不會影響外部 ...
  • 1/javascript誕生/作用 javascript誕生於:1995年 當時作用:客戶端數據驗證 開發公司:Netscape 發展至今:各種交互(包括於瀏覽器),數據驗證,單頁面應用,非同步載入... 2/javascript組成 ECMAScript(核心),DOM(文檔對象模型),BOM(瀏覽 ...
  • × 目錄 [1]定義 [2]關鍵幀 [3]動畫屬性 [4]多值 [5]API 前面的話 transition過渡是通過初始和結束兩個狀態之間的平滑過渡實現簡單動畫的;而animation則是通過關鍵幀@keyframes來實現更為複雜的動畫效果。本文將介紹關於animation動畫的相關知識 定義 ...
  • <script type="text/javascript"> var refid='dasdasd,dadsad'; var reg =/^([\u0391-\uFFE5\d\w,])*([\u0391-\uFFE5\d\w]+)$/; if(refid != "") { if(reg.exec( ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...