transform 属性 实现旋转木马效果

2,312 阅读2分钟

搭建舞台

...

   <style type="text/css">
      .main{
        width: 900px;
        min-height: 100px;
        margin:0 auto;
        padding: 100px 50px;
        background-color: #f0f0f0;
        box-shadow: inset 0 0 3px rgba(0,0,0,.35);

        position: relative;
        top: 0;

        display: flex;
        justify-content: center;
      }

      .container{
        width: 128px;
        height: 100px;

        position: relative;
      }

      .inner{
        width: 128px;
        height: 100px;
        box-shadow: 0 1px 3px rgba(0,0,0,.5);

        position: absolute;
        bottom: 0;
      }

      .inner:nth-child(1) { transform: rotateY(   0deg );background-color: #ccffff; }
      .inner:nth-child(2) { transform: rotateY(  40deg );background-color: #ccccff; }
      .inner:nth-child(3) { transform: rotateY(  80deg );background-color: #99ffff; }
      .inner:nth-child(4) { transform: rotateY( 120deg );background-color: #99ffcc; }
      .inner:nth-child(5) { transform: rotateY( 160deg );background-color: #ffccff; }
      .inner:nth-child(6) { transform: rotateY( 200deg );background-color: #ffcccc; }
      .inner:nth-child(7) { transform: rotateY( 240deg );background-color: #ffffcc; }
      .inner:nth-child(8) { transform: rotateY( 280deg );background-color: #ccff00; }
      .inner:nth-child(9) { transform: rotateY( 320deg );background-color: #99ff00; }
   </style>
   
...

    <!-- 舞台 -->
    <div class="main">
      <!-- 容器 -->
      <div id="container" class="container">
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
        <div class="inner"></div>
      </div>
    </div>

...

效果图

  • 我们对方块设置了按Y轴进行旋转,看见的只是方块变小,没有按Y轴旋转。是因为现在还是处于2D视角,没有透视效果。

加入 perspective 属性

  1. perspective 属性 指定了观察者与 z = 0 平面的距离,使具有三维位置变换的元素产生透视效果。
  2. perspective 属性只影响 3D 转换元素。
  3. 透视点是在浏览器的前方,所以perspective 属性设置后值后,元素会进大远小。
  4. 默认情况下,消失点位于元素的中心(视点),但是可以通过设置 perspective-origin 属性来改变其位置。
...

     .main{
       ...
        -webkit-perspective: 800px;
        -moz-perspective: 800px;
        perspective: 800px;
      }
      
...

效果图

  • 添加属性后就能看见,方块的旋转效果了。
  • 这时可以看见其他方块被最后一个方块遮住。这是因为方块是在2D空间旋转的。

加入 transform-style 属性

  1. 属性 transform-style 设置元素的子元素是位于 3D 空间中还是平面中。
  2. flat | preserve-3dflat元素的子元素位于该元素的平面中,preserve-3d元素的子元素应位于 3D 空间中。
...
      .container{
        ...

        -webkit-transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
        transform-style: preserve-3d;
      }
...

效果图

  • 这里就按我们的要求,所有方块都按y轴旋转了。
  • 不过现在都是挤在一起的。就要使用transform 属性让方块分散开来。

加入 translateZ() 函数

  1. 修改元素 z轴 在三维空间的位置。
...

      .inner:nth-child(1) { transform: rotateY(   0deg ) translateZ(200px);background-color: #ccffff; }
      .inner:nth-child(2) { transform: rotateY(  40deg ) translateZ(200px);background-color: #ccccff; }
      .inner:nth-child(3) { transform: rotateY(  80deg ) translateZ(200px);background-color: #99ffff; }
      .inner:nth-child(4) { transform: rotateY( 120deg ) translateZ(200px);background-color: #99ffcc; }
      .inner:nth-child(5) { transform: rotateY( 160deg ) translateZ(200px);background-color: #ffccff; }
      .inner:nth-child(6) { transform: rotateY( 200deg ) translateZ(200px);background-color: #ffcccc; }
      .inner:nth-child(7) { transform: rotateY( 240deg ) translateZ(200px);background-color: #ffffcc; }
      .inner:nth-child(8) { transform: rotateY( 280deg ) translateZ(200px);background-color: #ccff00; }
      .inner:nth-child(9) { transform: rotateY( 320deg ) translateZ(200px);background-color: #99ff00; }
      
...

效果图

  • 这样一个简单的静态效果就出来了

加入交互效果

...

     .container{
        ...
        
        /* 添加过度动画 */
        -webkit-transition: -webkit-transform 1s;
        -moz-transition: -moz-transform 1s;
        transition: transform 1s;
      }
      
...

  <body>
    ...
    <script type="text/javascript">
      var container = document.getElementById("container");
      var deg = 0;
      container.onclick = function(e){
        deg = deg + 40;
        container.style.transform = `rotateY(${deg}deg)`;
      }
    </script>
  </body>
...
  • 可以选择 旋转容器 或则 修改每个方块的旋转度数。这里直接旋转的容器。
  • 每次加 40 是因为我们,默认每个方块都多旋转 40 度。
  • 还需要一个过度效果 添加transition属性,css自动实现每一帧的动画。

效果图