一個三維物體(一個長方體),它圍繞着一個軸旋轉。我已經有過一些與css 3d一塊兒工做的經驗,而且我腦海裏開始出現了一個解決方案。我搜索了像「css 3d立方體」這樣的關鍵詞來確認個人想法。css
對技術感興趣的朋友能夠加我前端學習裙 學習編號:落葉,213126486,一塊兒討論進步~前端
讓我提醒你關於瀏覽器軸的事情。不是戰爭軸心,而是數字線路.。在三維笛卡爾座標系中,咱們都學到了一樣的軸。瀏覽器
三維空間的笛卡爾座標系是一對垂直的直線(軸)的有序三重奏,全部三個軸都有一個長度單位,每一個軸都有一個方向。
維基百科:笛卡爾座標系併發
下圖顯示瞭如何在瀏覽器中指向軸。ide
一種直角座標系,它指向觀察者。(圖像信用:維基百科)svg
x軸是水平的,y軸是垂直的,z軸從屏幕內出來。z軸零點值位於屏幕的平面上。記住這個事實。函數
要建立一個3D對象,我須要一個帶有透視圖的元素(讓咱們稱之爲「場景」)。透視圖是場景的深度,它取決於它包含的對象的大小。性能
.scene { perspective: 800px; }
若是透視圖過小,物體就會被扭曲。若是它太大,3D效果就會減小到零。學習
此外,場景中的全部對象只有一個視角。而三維效應則取決於視點位置。測試
那麼,如何計算視角呢?我發現它取決於轉動軸。對於x軸來講,它是一個高度值乘以4,它適合,對於y軸-寬度值乘以4。這是個人魔術公式:
const perspective = dimension * 4;
在肯定透視圖以後,我開始建立一個3D對象。我選擇了一個立方體,由於它是簡單的和可預測的。多維數據集元素是一個有寬度和高度定義的正則div(例如,200px
並使用相對定位。它經過如下方式轉換成一個3d對象transform-style
屬性的屬性preserve-3d
.。它告訴瀏覽器根據3d世界的規則呈現全部嵌套元素。
在個人例子中,立方體有六個divs(「邊」),絕對定位。類名對應於側(後、左、右、上、下、前)的初始位置。如下是標記:
<div class="scene"> <div class="cube"> <div class="side back"></div> <div class="side left"></div> <div class="side right"></div> <div class="side top"></div> <div class="side bottom"></div> <div class="side front"></div> </div> </div>
默認狀況下,全部的側都是一個平面,因此我須要從新排列它們。下面是它的外觀:
由此產生的css:
.cube { position:relative; width: 200px; height: 200px; transform-style: preserve-3d; } .side { position: absolute; width: 200px; height: 200px; } .back { transform: translateZ(-100px); } .left { transform: translateX(-100px) rotateY(90deg); } .right { transform: translateX(100px) rotateY(90deg); } .top { transform: translateY(-100px) rotateX(90deg); } .bottom { transform: translateY(100px) rotateX(90deg); } .front { transform: translateZ(100px); }
若要旋轉多維數據集,我將transform
立方體元素的屬性,其值是沿着x軸旋轉到任意角度:
.cube { transform: rotateX(42deg); }
根據要求,我只是旋轉立方體,只沿着x軸,因此我不須要左和右的邊。我添加了字幕,與其他部分的初始位置重合。
我開始旋轉立方體,發現底部和背面的字幕都顯示顛倒:
爲了解決這個問題,我把每個側面旋轉了180度,沿着x軸旋轉:
.back { transform: translateZ(-100px) rotateX(180deg); } .bottom { transform: translateY(100px) rotateX(270deg); }
我開始用真實的內容來填補雙方的意見,並當即面臨另外一個問題。我須要有一些虛線顯示的線條,可是它們模糊並且看起來很糟糕。
很快我就意識到了問題所在。還記得當圖像擴展到屏幕以外的3d電視廣告,個人立方體是那樣的。
若是你能從左邊或右邊看這個立方體,你會發現它的中心在屏幕平面上(Z軸上爲零),而正面在屏幕外。所以,它增長了視覺和模糊。
爲了解決這個問題,我將立方體移到z軸上,將前側面放在屏幕的平面上:
.cube { transform:translateZ(-100px); }
這裏是幾乎準備好的立方體:
我想你已經注意到我用了魔法號碼100
沿着軸線移動。100
這是我測試立方體的一半高度。爲何一半的高度?由於,這是圓的半徑,它位於立方體的一側(顯然是正方形)。
const offset = dimension / 2;
若是我須要旋轉三角形棱鏡,圓就會被刻在三角形上。在這種狀況下,偏移量的計算公式以下:
const offset = dimension / (2 * Math.sqrt(3));
爲了考慮完成任務,我必須在不一樣瀏覽器中測試結果。
我在網上看到的照片讓我陷入了抑鬱狀態。爲了瞭解我所說的內容,請先看看下面的例子,您最喜歡的瀏覽器。我更改了一個屬性,致使在internetexplorer中顯示錯誤的多維數據集。
事實上,internetexplorer並不支持該屬性。transform-style
有價值preserve-3d
.。在上面的例子中,我替換了preserve-3d
到flat
.。
因此,我很難過,但不會放棄。問題是學習新東西的機會。此外,我接受了挑戰。
我正在尋找一種方法來建立一個3d對象而無需使用transform-style: preserve-3d
並發現了一種有用的財產:transform-origin
.。它是元素轉換的中心點。我建立了一個交互式示例,它將幫助您瞭解它的工做原理:
示例中元素的三維旋轉與立方體的前一面很是類似,不是嗎?那就是我用的。
我開始從新作立方體。我沒有必要與整個場景交互,因此我刪除了場景元素的透視圖屬性。還有…將它添加到每一個三維轉換中,由於如今每一個元素都獨立地轉換。此外,我爲每一個方面設置了新屬性-transform-origin
的值等於立方體中心的位置,backface-visibility: hidden
.。這就是風格改變的方式:
.scene { } .cube { position: relative; width: 200px; height: 200px; transform: perspective(800px) translateZ(-100px); } .side { position: absolute; transform-origin: 50% 50% -100px; backface-visibility: hidden; }
我必須把兩邊放在正確的地方。由於transform-origin
屬性,我不須要改變它們,只是繞軸旋轉。就像魔法同樣!讓咱們看看它是如何運做的:
下面是關於側放置的css:
.back { transform: perspective(800px) rotateY(180deg); } .top { transform: perspective(800px) rotateX(90deg); } .bottom { transform: perspective(800px) rotateX(-90deg); } .front { transform: perspective(800px); }
在這裏,您能夠看到新的多維數據集正在運行:
第二個立方體看起來和旋轉的與第一個相同。可是在這種狀況下,您須要單獨地轉換各個方面。也許不是太容易。尤爲是當你想控制旋轉的中間角度時。
此外,若是你在Chrome中打開這個例子,你能夠看到在旋轉的時候兩邊都閃爍着。這很使人沮喪。
最後,我使用了兩個方法簡單試驗在...transform-style: preserve-3d
.。第一個多維數據集是默認的。第二個多維數據集是用於internetexplorer和不支持preserve-3d
.
最後,我不得不執行視差。一般狀況下,它會對用戶的行爲作出反應。它能夠是鼠標光標或滾動條的位置。但此次,效果取決於旋轉角度。
那麼我有什麼數據。首先,標題位置的起始點和結束點,或使其簡單,它的offset
從側面的中心上下向上。第二,angle
立方體旋轉。
我花了好幾個小時來想出一個公式,而後我就明白了。這就是我所記得的:
正弦和餘弦函數圖。(圖像信用:維基百科)
藉助餘弦和餘弦的幫助,我很容易地計算出每一個標題的偏移量取決於角度。下面是我所獲得的公式:
const front_offset = offset * sin(angle) * -1; const bottom_offset = offset * cos(angle); const back_offset = offset * sin(angle); const top_offset = offset * cos(angle) * -1;
任務完成了,如今我能夠享受結果並與你分享。使用滾動條或箭頭鍵旋轉該宣傳片塊。另外,嘗試拉上下右邊的黑色三角形來手動控制旋轉角度(不幸的是,這個特性在internetexplorer中不起做用)。看起來很不錯不是嗎?此外,性能也至關高(約爲60fps)。
我已經得到了使用css 3d的有用經驗,並發現了許多新有趣的屬性。但最重要的是,我已經意識到一我的永遠不會放棄。最有可能的是,你能夠找到另外一種方法來完成這項任務。
我但願你能享受個人故事。對技術感興趣的朋友能夠加我裙 學習編號:落葉,213126486,一塊兒討論進步~