?

新型3D Panorama技術解剖全息視頻

CSS3 3D技術

前言

3D 全景并不是什么新鮮事物了,但以前我們在 Web 上看到的 3D 全景一般是通過 Flash 實現的。若我們能將 CSS3 Transform 的相關知識運用得當,也是能實現類似的效果。換句話說,3D 全景其實就是 CSS3 3D 的應用場景之一。
準備
在實現 CSS3 3D 全景之前,我們先理清部分 CSS3 Transform 屬性:
transform-origin:元素變形的原點(默認值為 50% 50% 0,該數值和后續提及的百分比均默認基于元素自身的寬高算出具體數值);
perspective: 指定了觀察者與 z=0 平面的距離,使具有三維位置變換的元素產生透視效果。(默認值:none,值只能是絕對長度,即負數是非法值);
transform-style:用于指定其為子元素提供 2D 還是 3D 的場景。另外,該屬性是非繼承的;
transform:該屬性能讓你修改 CSS 可視化模型的坐標空間,其中包括 平移(translate)、旋轉(rotate)、縮放(scale) 和 扭曲(skew)。
下面對上述的一些點進行更深入的分析:
對于 perspective,該屬性指定了“眼睛”與元素的 perspective-origin (默認值是 50% 50%)點的距離。那么問題來了:“當我們應用 px 作為衡量單位時,那它的實際距離該如何量化呢(即如何得到我們熟悉且易于表達的距離)?”
答:當我們的屏幕的分辨率是 1080P(1920*1080px),且該元素或祖先元素的 perspective 值是 1920px 時,該應用了 CSS3 3D Transform 的元素的立體效果就相當于我們在距離一個屏幕寬度(1920px)的屏幕前觀看該元素的真實效果。盡管如此,目前我也不清楚如何準確地為元素設置一個合適的 perspective 值,只能猜測個大概值,然后再動態修改值,以達到滿意的呈現效果。

根據 相似三角形 的性質可計算出被前移的元素最終在屏幕上顯示的實際大小

  • 另外,關于 perspective 還有另外一個重要的點。因為,perspective-origin 的默認值是 50% 50%,因此,對哪個元素應用 perspective 屬性,就決定了“眼睛”的位置(即我們的“眼睛”是在哪個角度看物體)。一般來說,當我們需要正視物體時,就會將該屬性設置在與該元素中心重合的某一祖先元素上。

    再另外,如果說:“如何讓一個元素(的背面)不可見?”,你可能會說 backface-visibility:hidden;。其實,對于在“眼睛”背后的元素(以元素的 transform-origin 為參考點),即元素的z軸坐標值大于 perspective 的值,瀏覽器是不會將其渲染出來的。

  • 對于 transform-style,該屬性指定了其子元素是處于 3D 場景還是 2D 場景。對于 2D 場景,元素的前后位置是按照平時的渲染方式(即若在普通文檔流中,是按照代碼中元素的先后順序,后面的元素會遮住在其前面的元素);對于 3D 場景,元素的前后位置則按照真實世界的規則排序(即越靠近“眼睛”的,會遮住離“眼睛”更遠的元素)。

    另外,由于 transform-style 屬性是非繼承的,對于中間節點需要顯式設定。

  • 對于 transform 屬性:下圖整理了 rotate3d、translate3d 的變換方向:

    transform 中的變換屬性的順序是有關系的,如 translateX(10px) rotate(30deg) 與 rotate(30deg) translateX(10px) 是不等價的。另外,需要注意的是 scale 中如果有負數值,則該方向會產生 180 度的翻轉;再另外,部分 transform 效果會導致元素(字體)模糊,如 translate 的數值存在小數、通過 translateZ 或 scale 放大元素等等。每個瀏覽器都有其不同的表現。
    實現

    上面理清了一些 CSS Transform 的知識點,下面就講講如何實現 CSS 3D 全景 :
    想象一下,當我們站在十字路口中間,身體不動,頭部旋轉 360°,這個過程中所看到的畫面就形成了一幅以你為中心的全景圖了。其實,當焦距不變時,我們就等同于站在一個圓柱體的中心。
    但是,虛擬世界與現實的最大不同是:沒有東西是連續的,即所有東西都是離散的。例如,你無法在屏幕上顯示一個完美的圓。你只能以一個正多邊形表示圓:邊越多,圓就越“完美”。
    同理,在三維空間,每個 3D 模型都等同于一個多面體(即 3D 模型只能由不彎曲的平面組成)。當我們討論一個本身就是多面體(如立方體)的模型時并不足以為奇,但當我們想展示其它模型時,如球體時,就需要記住這個原理了。

    淘寶造物節活動首頁 就是 CSS 3D 全景的一個很贊的頁面,它將全景圖分隔成 20 等份,相鄰的元素間差 18°(360/20)。需要注意的是:我們要確保每個元素的正面是指向圓柱中心的,所以要計算好每等份的旋轉角度值。然后再將元素向外(即 Z 軸方向)平移 r px。對于立方體 r 就是 邊長/2,而對于其它更復雜的正多面體呢?


    俯視時所看到的元素外移動畫

    可由下圖看出,將水平的 4 張圖片合成后就是一張全景圖:

    理解上述知識后,就可以通過為元素設置合適的 CSS3 Transform 屬性值,即可實現一張可交互的全景圖了。當然,交互的效果可以是拖拽,也可以是重力感應等。
    正如在上文提到的:“沒有東西是連續的,即所有東西都是離散的…”。將《造物節》與后續全景圖的水平方向上的圖片分別合成一張圖后,可以發現:圖片數量越多,圖片的要求也越低。你覺得呢?

    基本要求:

    1. 水平方向上需要首尾相連;
    2. 因為效果圖最終需要切成 N 等份,所以盡可能讓 設計圖的寬度能被 N 整除;
    3. 圖片尺寸不僅要考慮正視圖的大小,還要考慮元素在旋轉時依然能覆蓋視野(可選)。

     


     


     


 

?
上海时时三星走势图