数据可视化-CSS3动画

73 阅读4分钟

一、2D动画

1. transform

  • 平移:translate(x, y)
  • 缩放:scale(x, y)
  • 旋转:rotate(deg)
  • 倾斜:skew(deg, deg)

2. 坐标系

  • CSS3 transform属性允许在二维或三维空间中直观地变换元素。
    • transform属性会转换元素的坐标系,使元素在空间中转换。
    • 用transform变换的元素会受transform-origin属性值的影响,该属性用于指定形变的原点。
  • 元素的坐标系
    • CSS中的每个元素都有一个坐标系,其原点位于元素的左上角,被称为初始坐标系。
    • 用transform时,坐标系的原点默认会移动到元素的中心(因为transform-origin的默认值是50% 50%)。
    • 用transform属性旋转或者倾斜时,会变换或倾斜元素的坐标系。并且该元素所有后续变换都将基于新坐标系的变换。
    • 因此,transform属性中变换函数的顺序非常重要——不同的顺序会导致不同的变换结果。
  • transform-origin
    • 一个值:设置x轴的原点,y轴为默认50%。
    • 两个值:设置x轴和y轴的原点。
    • 三个值:设置x轴、y轴和z轴的原点。

二、transition和animation

1. transition

  • transition-property
    • 规定设置过渡效果的css属性名称
  • transition-duration
    • 规定完成过渡效果需要多少秒或毫秒
  • transition-timing-function
    • 指定过渡动画,规定速度效果的速度曲线
  • transition-delay
    • 指定开始出现的延迟时间

2. animation

  • animation-name
    • 指定要绑定要选择器的关键帧的名称
  • animation-duration
    • 定义动画一个周期需要多少秒或毫秒
  • animation-iteration-count
    • 定义动画应该播放多少次
  • animation-direction
    • 定义是否循环交替反向播放动画
  • animation-timing-function
    • 指定动画将如何完成一个周期

三、3D动画

1. transform

  • 3D位移:translate3d(tx, ty, tz)
    • translateX(tx)
    • translateY(ty)
    • translateZ(tz)
  • 3D缩放:scale3d(sx, sy, sz)
    • scaleX(sx)
    • scaleY(sy)
    • scaleZ(sz)
  • 3D旋转:rotate3d(x, y, z, a)
    deg为正数,旋转将为顺时针;为负数,则为逆时针。
    • rotateX(deg)
    • rotateY(deg)
    • rotateZ(deg)

2. 3D透视 - perspective

01-3D透视的说明.jpg

  • 什么是透视
    • 定了观察者与z=0平面的距离,使具有三维位置变换的元素产生透视效果(z表示Z轴)。
    • z>0的三维空间比正常的大,而z<0时则比正常的小,大小程度由该属性的值决定。
  • perspective的值
    • none
    • length:当值为0或者负数时,无透视变换。
  • 两种使用方式
    • 父元素中使用
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        body {
          margin: 0;
          bottom: 0;
        }
        .box {
          position: relative;
          width: 200px;
          height: 100px;
          background-color: skyblue;
    
          /* 父元素增加透视 */
          perspective: 50px;
        }
    
        .item {
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          background-color: pink;
          /* 形变 */
          transform: rotateY(60deg);
        }
    
    
      </style>
    </head>
    <body>
      <div class="box">
        div
        <div class="item">10</div>
      </div>
    </body>
    </html>
    
    • 当前元素使用
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        body {
          margin: 0;
          bottom: 0;
        }
        .box {
          position: relative;
          width: 200px;
          height: 100px;
          background-color: skyblue;
    
          /* 当前元素增加透视 */
          transform: perspective(200px) rotateY(60deg);
        }
    
    
      </style>
    </head>
    <body>
      <div class="box">
        div
      </div>
    </body>
    </html>
    

3. 3D空间 - transform-style

  • transform-style
    • 该CSS元素用于设置元素的子元素是定位在3D空间中还是平展在元素的2D平面中。
    • 在3D空间中同样是可以使用透视效果。
    • flat:指示元素的子元素位于元素本身的平面中。
    • preserve-3d:指示元素的子元素应位于3D空间中。
  • 案例
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <link rel="stylesheet" href="style.css">
    </head>
    <body>
      <div class="webpack-logo">
        <!-- cube-inner -->
        <ul class="cube-inner">
          <li class="top"></li>
          <li class="bottom"></li>
          <li class="front"></li>
          <li class="back"></li>
          <li class="left"></li>
          <li class="right"></li>
        </ul>
    
        <!-- cube-outer -->
        <ul class="cube-outer">
          <li class="top"></li>
          <li class="bottom"></li>
          <li class="front"></li>
          <li class="back"></li>
          <li class="left"></li>
          <li class="right"></li>
        </ul>
    
      </div>
    </body>
    </html>
    
    html, body {
      padding: 0;
      margin: 0;
      width: 100%;
      height: 100%;
      background-color: #2b3a42;
    
      display: flex;
      justify-content: center;
      align-items: center;
      list-style: none;
    }
    
    ul {
      margin: 0;
      padding: 0;
      list-style: none;
    }
    
    .webpack-logo {
      width: 100%;
      height: 200px;
      position: relative;
    }
    
    /* cube-inner */
    .cube-inner {
      position: absolute;
      left: 50%;
      top: 50%;
      margin: -25px 0 0 -25px;
      width: 50px;
      height: 50px;
      /* 启用3D空间 */
      transform-style: preserve-3d;
      transform: rotateX(-33.5deg) rotateY(45deg);
      animation: innerLoop 6s ease-in-out infinite;
    }
    
    @keyframes innerLoop {
      0% {
        transform: rotateX(-33.5deg) rotateY(45deg);
      }
      50%, 100% {
        transform: rotateX(-33.5deg) rotateY(-315deg);
      }
    }
    
    .cube-inner li {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: #175d96;
      border: 1px solid #fff;
    }
    
    .cube-inner .top {
      transform: rotateX(90deg) translateZ(25px);
    }
    
    .cube-inner .bottom {
      transform: rotateX(-90deg) translateZ(25px);
    }
    
    .cube-inner .front {
      transform: rotateY(0deg) translateZ(25px);
    }
    
    .cube-inner .back {
      transform: rotateY(-180deg) translateZ(25px);
    }
    
    .cube-inner .left {
      transform: rotateY(-90deg) translateZ(25px);
    }
    
    .cube-inner .right {
      transform: rotateY(90deg) translateZ(25px);
    }
    
    /* cube-outer */
    .cube-outer {
      position: absolute;
      left: 50%;
      top: 50%;
      margin: -50px 0 0 -50px;
      width: 100px;
      height: 100px;
      /* 启用3D空间 */
      transform-style: preserve-3d;
      transform: rotateX(-33.5deg) rotateY(45deg);
      animation: outerLoop 6s ease-in-out infinite;
    }
    
    .cube-outer li {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(141, 214, 249, .5);
      border: 1px solid #fff;
    }
    
    .cube-outer .top {
      transform: rotateX(90deg) translateZ(50px);
    }
    
    .cube-outer .bottom {
      transform: rotateX(-90deg) translateZ(50px);
    }
    
    .cube-outer .front {
      transform: rotateY(0deg) translateZ(50px);
    }
    
    .cube-outer .back {
      transform: rotateY(-180deg) translateZ(50px);
    }
    
    .cube-outer .left {
      transform: rotateY(-90deg) translateZ(50px);
    }
    
    .cube-outer .right {
      transform: rotateY(90deg) translateZ(50px);
    }
    
    @keyframes outerLoop {
      0% {
        transform: rotateX(-33.5deg) rotateY(45deg);
      }
      50%, 100% {
        transform: rotateX(-33.5deg) rotateY(405deg);
      }
    }
    

4. 3D背面可见性 - backface-visibility

  • backface-visibility
    • 该CSS属性指定某个元素当背面朝向观察者时是否可见。
    • visible:背面朝向用户时可见。
    • hidden:背面朝向用户时不可见。

5. 动画性能优化

  • 创建一个新的渲染层(减少回流)
    • 有明确的定位属性(position: relative、fixed、sticky、absolute)
    • 透明度(opacity小于1)
    • 有transform属性(不为none)
    • backface-visibility: hidden
  • 创建合成层(合成层会开始CPU加速页面渲染,但不能滥用)
    • 对opacity、transform、filter、backdropfilter应用了animation或transition
    • 有3Dtransform函数
    • will-change设置为opacity、transform、top、left、bottom、right