[CSS]一起來畫立方體: CSS transform屬性

在學習transition, transform和translate這三個屬性的時候,發現了一個例子包括了以下幾個屬性,覺得挺有意思,對學習這三個屬性也很有幫助。

  • transform
  • translate
  • rotate
  • perspective
  • perspective-origin

先看看MDN上一個CSS屬性 perspective 的一個例子
https://developer.mozilla.org/zh-CN/docs/Web/CSS/perspective-origin

<div class="container">
  <div class="cube pers">
    <div class="face front">1</div>
    <div class="face back">2</div>
    <div class="face right">3</div>
    <div class="face left">4</div>
    <div class="face top">5</div>
    <div class="face bottom">6</div>
  </div>
</div>
<style>
  .pers {
    perspective: 350px;
  }

  .container {
    width: 200px;
    height: 200px;
    margin: 100px 0 0 100px;
    border: none;
  }

  .cube {
    width: 100%;
    height: 100%;
    backface-visibility: visible;
    perspective-origin: 150% 150%;
    transform-style: preserve-3d;
  }

  .face {
    display: block;
    position: absolute;
    width: 100px;
    height: 100px;
    border: none;
    line-height: 100px;
    font-family: sans-serif;
    font-size: 60px;
    color: white;
    text-align: center;
  }

  /* Define each face based on direction */
  .front {
    background: rgba(0, 0, 0, 0.3);
    transform: translateZ(50px);
  }

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

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

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

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

  .bottom {
    background: rgba(196, 0, 196, 0.7);
    transform: rotateX(-90deg) translateZ(50px);
  }
</style>

效果圖:


立方體.png

這個例子是HTML+CSS畫出來的一個正方體,它是怎么做的呢?

HTML代碼非常簡單,一個container裝了一個cube,這個cube有6個face。

CSS部分,每個face都是100×100 px的正方形,每個face的transform屬性不一樣,由不同的translate和rotate的值組成。嘗試把每個face的transform屬性去掉,來看看效果。

把transform屬性去掉后的效果.png

6個面堆疊在一起了,由些可見,正方體就是6個平面正方形經過旋轉和平移,構成一個正方體,這個我們實際的操作也很一致。

先來看看立體的x y z坐標系:


坐標系.png

結合坐標系:

  1. 正面front:把正方形沿z軸平移50px
transform: translateZ(50px);
  1. 背面back:把正方形沿z軸平移50px,并以y軸旋轉順時針180度
transform: rotateY(180deg) translateZ(50px);
  1. 右面right:把正方形沿z軸平移50px,并以y軸旋轉順時針90度
transform: rotateY(90deg) translateZ(50px);
  1. 左面left:把正方形沿z軸平移50px,并以y軸逆時針旋轉90度
transform: rotateY(-90deg) translateZ(50px);
  1. 上面top:把正方形沿z軸平移50px,并以x軸順時針旋轉90度
transform: rotateX(90deg) translateZ(50px);
  1. 底面bottom:把正方形沿z軸平移50px,并以x軸逆時針旋轉90度
transform: rotateX(-90deg) translateZ(50px);

只看概念是不是還是有點難想象呢?這時候,我們可以加上transition屬性,用動畫效果還幫我們看看。

每一個face加一個觸發事件,加上"transition : '2s'"

添加button.png

依次點擊每個button,可以看到face從開始的位置變換到正方體的位置。transiton的作用就是給一個2s的時間,讓我們看到變化的過程。


效果.png

完整代碼

<div class="container">
  <div class="cube pers">
    <div class="face front">1</div>
    <div class="face back">2</div>
    <div class="face right">3</div>
    <div class="face left">4</div>
    <div class="face top">5</div>
    <div class="face bottom">6</div>
  </div>
</div>
<button onclick="changeFront()">Front</button>
<button onclick="changeBack()">Back</button>
<button onclick="changeRight()">Right</button>
<button onclick="changeLeft()">Left</button>
<button onclick="changeTop()">Top</button>
<button onclick="changeBottom()">Bottom</button>
<style>
  .pers {
    perspective: 350px;
  }
  .container {
    width: 200px;
    height: 200px;
    margin: 100px 0 0 100px;
    border: none;
  }
  .cube {
    width: 100%;
    height: 100%;
    backface-visibility: visible;
    perspective-origin: 150% 150%;
    transform-style: preserve-3d;
  }
  .face {
    display: block;
    position: absolute;
    width: 100px;
    height: 100px;
    border: none;
    line-height: 100px;
    font-family: sans-serif;
    font-size: 60px;
    color: white;
    background-color: thistle;
    text-align: center;
  }

  /* Define each face based on direction */
</style>

<script>
  function changeFront() {
    let face = document.querySelector(".face.front");
    face.style.background = 'rgba(0, 0, 0, 0.3)';
    face.style.transform = 'translateZ(50px)';
    face.style.transition = '2s'
  }
  function changeBack() {
    let face = document.querySelector(".face.back");
    face.style.background = 'rgba(0, 255, 0, 1)';
    face.style.transform = 'rotateY(180deg) translateZ(50px)';
    face.style.transition = '2s'
  }
  function changeRight() {
    let face = document.querySelector(".face.right");
    face.style.background = 'rgba(196, 0, 0, 0.7)';
    face.style.transform = 'rotateY(90deg) translateZ(50px)';
    face.style.transition = '2s'
  }
  function changeLeft() {
    let face = document.querySelector(".face.left");
    face.style.background = 'rgba(0, 0, 196, 0.7)';
    face.style.transform = 'rotateY(-90deg) translateZ(50px)';
    face.style.transition = '2s'
  }
  function changeTop() {
    let face = document.querySelector(".face.top");
    face.style.background = 'rgba(196, 196, 0, 0.7)';
    face.style.transform = 'rotateX(90deg) translateZ(50px)';
    face.style.transition = '2s'
  }
  function changeBottom() {
    let face = document.querySelector(".face.bottom");
    face.style.background = 'rgba(196, 0, 196, 0.7)';
    face.style.transform = 'rotateX(-90deg) translateZ(50px)';
    face.style.transition = '2s'
  }
</script>

總結一下,rotate和translate都是transform的子屬性,后面加上X Y Z代表以x軸、y軸、z軸為基礎旋轉/平移。

  • transform: CSS變換函數,可以旋轉,縮放,傾斜或平移給定元素。
    • rotate:正數時順時針旋轉,負數時逆時針旋轉
    • translate: 正數時正方向平移,負數時反方向平移
  • transition: CSS過渡函數

另外,perspective屬性:[CSS]一起來畫立方體: CSS perspective屬性

參考:
https://www.w3.org/TR/css-transforms-2
https://drafts.csswg.org/css-transitions
https://developer.mozilla.org/zh-CN/docs/Web/CSS/transform
https://developer.mozilla.org/zh-CN/docs/Web/CSS/transition

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容