變形(transform) 3D基本使用

變形的3D應用是以2D為基礎知識,所以你會發現幾乎所有的變形函式的名稱都差不多。

perspective屬性

實際上螢幕上只有2維,3維是模擬出來的效果。也就是以2次元模擬出3次元的形狀。3D相較於2D多了一個Z軸的數值。基礎的3D的三個軸,X軸是螢幕上的水平座標軸,Y軸是垂直座標軸,Z軸則是由螢幕射出的另一個虛擬的座標軸,它代表的是DOM元素(或物件)的遠近距離。負值的Z軸數值是比原先的元素還愈遠,也就是愈小,正值代表愈近,也就是愈大。

perspective中文是"透視"的意思,在3D設計中是一個重要的屬性,它代表了Z軸為0(z=0)到觀看者的距離(也可以稱為深度),以這個觀測距離來決定物件的大小(遠近)情況,當超過這個觀測距離,DOM元素(物件)將會不可見。根據這份資料的說明,perspective設定為300px或更少時,會有強烈的失真,500px到1000px的失真較為中等,2000px以上的失真就很輕微。

一般來說,我們會在要進行3D變形的外層容器元素來定義perspective,這樣包含在其內的子元素(物件)都可以按照這個深度來進行變形。perspective的設定方式有兩種,一種是直接定義perspective屬性:

perspective: 500px;

另一種是定義在transform中,以類似函式的方式來定義數值:

transform: perspective(250px);

一個使用rotateX旋轉正45度的範例如下,你可以增加或減少perspective的數值來觀察變形的情況:

See the Pen by eyesofkids (@eyesofkids) on CodePen.

https://drafts.csswg.org/css-transforms/#perspective

https://developer.apple.com/library/safari/documentation/InternetWeb/Conceptual/SafariVisualEffectsProgGuide/Using2Dand3DTransforms/Using2Dand3DTransforms.html

http://www.slideshare.net/kswlee/css3-2d3d-transform

https://www.git-tower.com/blog/css3-transforms/

https://dev.opera.com/articles/understanding-3d-transforms/#perspective

以下為最簡單的兩種範例:

下面是使用perspective(透視)加上translateZ(以Z軸平移)的範例,你可以看到當移動的長度為負數與正數的差異。

See the Pen by eyesofkids (@eyesofkids) on CodePen.

下面是使用perspective(透視)加上rotateXrotateYrotateZ(以各軸旋轉)的範例。

See the Pen by eyesofkids (@eyesofkids) on CodePen.

觀測者的原點是可以用另一個屬性perspective-origin來改變,稱之為透視原點或消失點(vanishing point, 到最遠處消失的那個點),這個屬性可以使用X軸與Y軸的長度數值或百分比(原點為0%),或是像或是用top/center/bottom、left/center/right等組合來直接定義新的位置,正中央為50%,數值是center。perspective-originperspective合併可以形成透視矩陣(perspective matrix)。

https://www.smashingmagazine.com/2016/07/front-end-challenge-accepted-css-3d-cube/

要進一步講解3D的特性需要先畫出一個cube(正方體, 骰子),比較容易理解。我們用變形函式中的rotate與translate搭配,可以先畫出一個正方體。

HTML碼的基本結構如下,scene是一個場景,cube則是在這個場景中的正方體,一個正方體有6個面,也就是6個2D的區塊,分別以前後上下左右來區分:

<div class="scene">
  <div  class="cube">
    <div class="front"></div>
    <div class="back"></div>
    <div class="top"></div>
    <div class="bottom"></div>
    <div class="left"></div>
    <div class="right"></div>
  </div>
</div>

每一面的CSS共同的屬性定義如下,我們定義它為200x200像素的大小,並可在裡面呈現置中的文字,文字的顏色、大小等等定義。其中有一個屬性backface-visibility,它可以控制要不要看到被擋住的那些面,可以使用visiblehidden,預設是看不到被擋住的面也就是hidden。這裡的範例是使用visible,讓我們能透視看得到被擋住的面:

.cube div {
  display: block;
  position: absolute;
  width: 200px;
  height: 200px;
  line-height: 200px;
  font-size: 40px;
  color: white;
  text-align: center;
  backface-visibility: visible;
}

前面(front)與後面(back)的定義最為簡單,除了各自的顏色外,前面(front)即是由Z軸向外(向使用者)突出100px,100px即是整個正方體邊長200px的一半。後面(back)則是再加上以Y軸為準旋轉180度的變形即可。

.front {
  background: rgba(0, 0, 0, 0.4);
  transform: translateZ(100px);
}

.back {
  background: rgba(0, 255, 0, 1);
  transform: rotateY(180deg) translateZ(100px);
}

再來是上面(top)與下面(bottom),除了以Z軸平移100px外,加上以X軸為準的旋轉90度與-90度就完成了。

.top {
  background: rgba(196, 0, 0, 0.7);
  transform: rotateX(90deg) translateZ(100px);
}

.bottom {
  background: rgba(196, 0, 196, 0.7);
  transform: rotateX(-90deg) translateZ(100px);
}

左面(left)與右面(right),除了以Z軸平移100px外,再加上以Y軸為準旋轉90度與-90度的變形即可,這與背面(back)有點類似。

.left {
  background: rgba(0, 0, 196, 0.7);
  transform: rotateY(-90deg) translateZ(100px);
}

.right {
  background: rgba(196, 196, 0, 0.7);
  transform: rotateY(90deg) translateZ(100px);
}

再回到.cube的定義中,只有設定一個transform-style屬性,這個屬性代表它的子元素要使用3D的方式來進行位置指示。只有preserve-3dflat兩種值可用,預設是flat,也就是平面(平坦)的意思。

.cube {
  transform-style: preserve-3d;
}

最上層的scene是我們要用的場景類別,它的CSS定義如下,除了定義固定的寬與高之外,另外定義了perspectiveperspective-origin兩個屬性:

.scene {
  width: 200px;
  height: 200px;
  margin: 50px 0 0 50px;

  perspective: 800px;
  perspective-origin: 50% -150px;
}

perspective如同上面所說的,是透視的深度,與z=0之間的距離。perspective-origin則是透視原點(或消失點),這裡是使用中心點(50%)與向上偏移150px。

最後的範例結果如下,因為要讓它看起來像是個正方體,我加上了以Y軸旋轉的CSS3動畫:

See the Pen by eyesofkids (@eyesofkids) on CodePen.

這幾個屬性的用法都可以在正方體中看到。花點時間調整一下其中的數值應該很容易理解。

results matching ""

    No results matching ""