天天看點

【CSS進階】試試酷炫的 3D 視角

寫這篇文章的緣由是因為看到了這個頁面:

<a href="https://shakeduang.nuomi.com/campus/index.html?from=timeline&amp;isappinstalled=1" target="_blank">戳我看看(移動端頁面,使用模拟器觀看)</a>

運用 CSS3 完成的 3D 視角,雖然有一些暈3D,但是使人置身于其中的互動體驗感覺非常棒,運用在移動端制作一些 H5 頁面可謂十分博人眼球。

下面進入正文:(一些 Gif 圖檔較大,需要等待一會)

<a></a>

百聞不如一見,先直覺感受一下上述我所說的效果:

最好能點進去看看,這裡我使用了帶背景色的 div 作為示例,我們的視角處于一個正方體中,正方體的旋轉動畫讓我們有了 3D 的感覺。

那麼原本的圖長什麼樣呢?我們把距離拉遠,一探究竟:

是長這樣的:

【CSS進階】試試酷炫的 3D 視角

相較于第一種效果,其實所做的隻是将我們的視角推進到了正方體當中,有了一種身臨其景的感覺。

而合理的運用 CSS3 所提供的一些 3D 屬性,很容易就能達到上述的效果。

制作這樣一個 3D 圖形,我在之前的文章已經很詳細的講述了過程,感興趣的可以戳進去看看:

<a href="http://www.cnblogs.com/coco1s/p/5414153.html" target="_blank">【CSS3進階】酷炫的3D旋轉透視</a>

再簡單複述一下,主要是運用到了兩個 CSS 屬性:

要利用 CSS3 實作 3D 的效果,最主要的就是借助 transform-style 屬性。

transform-style 隻有兩個值可以選擇:

當父元素設定了 transform-style:preserve-3d 後,就可以對子元素進行 3D 變形操作了,3D 變形和 2D 變形一樣可以,使用 transform 屬性來設定,或者可以通過制定的函數或者通過三維矩陣來對元素變型操作:當我們指定一個容器的 transform-style 的屬性值為 preserve-3d 時,容器的後代元素便會具有 3D 效果,這樣說有點抽象,也就是目前父容器設定了 preserve-3d 值後,它的子元素就可以相對于父元素所在的平面,進行 3D 變形操作。

使用 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) 這種寫法。

簡單來說,當元素沒有設定 perspective 時,也就是當 perspective:none/0 時所有後代元素被壓縮在同一個二維平面上,不存在景深的效果。perspective 為一個元素設定三維透視的距離,僅作用于元素的後代,而不是其元素本身。

而如果設定 perspective 後,将會看到三維的效果。

我們上面之是以能夠在正方體外圍看到正方體,以及深入正方體内,都是因為 <code>perspective</code> 這個屬性。它讓我們能夠選擇推進視角,還是遠離視角,是以便有了 3D 的感覺。

為了完成這樣一個效果,需要一個靈活的布局,去控制整個 3D 效果的展示。

下面是我覺得比較好的一種方式:

最外層 <code>container</code> ,控制圖形的位置及在整個頁面上的布局;

<code>stage</code> 層,舞台層,從這裡開始設定 3D 景深效果,添加 perspective 視距;

<code>control</code> 層,動畫的控制層,通過這一層可以添加旋轉動畫或者在移動端的觸摸動畫,通過更改<code>translateZ</code> 屬性也可以拉近拉遠視角;

<code>imgWrap</code> 層,圖檔層,裝入我們要拼接的圖檔,下文會提及。

圖檔拼接其實才是個技術活,需要許多的計算。

以上述 Demo 中的正方體為例子,class 為 <code>img</code> 的 div 塊的高寬為 400px*400px。那麼要利用 4 個 這樣的 div 拼接成一個正方體,需要分别将 4 個 div 繞 Y 軸旋轉 [90°, 180°, 270°, 360°],再 <code>translateY(200px)</code> 。

值得注意的是,一定是先旋轉角度,再偏移距離,這個順序很重要。

看看俯視圖,也就是這個意思:

【CSS進階】試試酷炫的 3D 視角

這是最簡單的情況了,都是直角。

如果是一張圖需要分割成八份,假設每張圖分割出來的高寬為 400 400 , 8 張圖需要做的操作是依次繞 Y 軸旋轉 [45°, 90°, 135°, 180°, 225°, 270°, 315°, 360°] ,偏移的距離為 <code>translateY(482.84px)</code> ,也就是 (200 + 200√2)。

看看俯視圖:

【CSS進階】試試酷炫的 3D 視角

效果圖:

上面的示例都是使用的帶背景色的 div 塊,現在我們選取一張真正的圖檔,将其拼接成一個柱體。

下面這張圖,大小為 <code>3480px * 2000px</code> :

【CSS進階】試試酷炫的 3D 視角

我們把它分割為 20 份,拼成一個正 20 邊形,當然不用一塊一塊切圖下來,利用 <code>background-position</code> 就可以完成了。而且分割的份數越多,最終做出來的效果越像一個圓柱,效果也更加真實。

正 20 邊形,需要 20 個 div ,假設容器是 .img-bg1 ~ .img-bg20 ,那麼每塊圖檔的寬度為 <code>174px</code>,依次需要遞增的角度為 18° ,并且我們需要計算出需要偏移的距離為 <code>translateZ(543px)</code>。

可以利用一些 CSS 預處理器處理這段代碼,下面是 Sass 的寫法:

【CSS進階】試試酷炫的 3D 視角

可以看到,圖中近視為一個圓柱形,不過有一些小問題:

選取的圖檔必須是左右首尾相連的的,不然圓柱結合處會有明顯的不協調,這就要求要使用這種方式制作 H5 頁面的時候,美術出的設計圖必須左右相連無違和感。

另外一點就是分割的塊術,圖檔分割越多塊,越近視為為一個圓柱,效果更佳。

做到這一步,隻剩下最後一步,就是推進我們的視角,進入到圓柱内部,産生 3D 視圖的感覺。

我們通過 class 為 <code>control</code> 這個 div 控制這個效果,不過這裡控制我們進入圓柱内部的屬性不是調整修改 <code>perspective</code> 屬性,而是調整 <code>translateZ</code> 屬性。通過控制 translateZ 得到的畫面更加真實,可以自己嘗試一下分别控制 <code>perspective</code> 與 <code>translateZ</code> 得到的效果,便會有深刻的感受。

整個效果圖太大,隻截取了部分制作成 GIF:

【CSS進階】試試酷炫的 3D 視角

還有一個小問題,那就是進入到圓柱内部之後,整個圖檔都反了過來,是以我們可能需要利用PS将原圖進行一次左右翻轉,這樣進入内部之後,看到的就是原圖效果。

至此,整個頁面就算完工了,接下來的就是添加一些 touch 事件,增添一些細節。可能寫的過程中遺漏了一些細節,有什麼很難一下了解過來的地方可以在評論留言。

本文示例 Demo 已上傳在我的 Github 上:

<a href="https://github.com/chokcoco/Css33DView" target="_blank">Css33DView</a>

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