前端:用css打造炫酷3d特效- css3d立方體

一個三維物體(一個長方體),它圍繞着一個軸旋轉。我已經有過一些與css 3d一塊兒工做的經驗,而且我腦海裏開始出現了一個解決方案。我搜索了像「css 3d立方體」這樣的關鍵詞來確認個人想法。css

對技術感興趣的朋友能夠加我前端學習裙  學習編號:落葉,213126486,一塊兒討論進步~前端

削尖軸

讓我提醒你關於瀏覽器軸的事情。不是戰爭軸心,而是數字線路.。在三維笛卡爾座標系中,咱們都學到了一樣的軸。瀏覽器

三維空間的笛卡爾座標系是一對垂直的直線(軸)的有序三重奏,全部三個軸都有一個長度單位,每一個軸都有一個方向。
維基百科:笛卡爾座標系併發

下圖顯示瞭如何在瀏覽器中指向軸。ide

A right-handed three-dimensional Cartesian coordinate system with the Z-axis pointing towards the viewer.

一種直角座標系,它指向觀察者。(圖像信用:維基百科)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-3dflat.。

因此,我很難過,但不會放棄。問題是學習新東西的機會。此外,我接受了挑戰。

尋找支點

我正在尋找一種方法來建立一個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立方體旋轉。

我花了好幾個小時來想出一個公式,而後我就明白了。這就是我所記得的:

Graphs of the sine and cosine functions

正弦和餘弦函數圖。(圖像信用:維基百科)

藉助餘弦和餘弦的幫助,我很容易地計算出每一個標題的偏移量取決於角度。下面是我所獲得的公式:

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,一塊兒討論進步~

相關文章
相關標籤/搜索