Skip to content

css动画

2023-04-06
Author:lzugis

提示

CSS3 中有三个重要的动画属性,transition、animation和 transform。本篇文章主要对transition 中的 3D动画 进行学习了解。

CSS3 transform 属性不但允许你进行 2D 的旋转,缩放或平移指定的元素,还支持 3D 变换元素。

常见的函数 transform function 有:

  • 平移:translate3d(tx, ty, tz)
    • ✓ translateX(tx) 、translateY(ty)、translateZ(tz)
  • 缩放:scale3d(sx, sy, sz)
    • ✓ scaleX(sy)、scaleY(sy)、scaleZ(sz)、
  • 旋转:rotate3d(x, y, z, a)
    • ✓ rotateX(x)、rotateY(y)、rotateZ(z)

◼ 通过上面的几个函数,我们可以改变某个元素的 3D 形变。

◼ 3D 形变函数会创建一个合成层来启用GPU硬件加速,比如: translate3d、translateZ、 scale3d 、 rotate3d ...

1. 3D旋转

1.1 rotateZ 、rotateX、rotateY

  • 旋转:rotateX(deg)、rotateY(deg)、rotateZ(deg)
    • 该 CSS 函数定义一个变换,它将元素围绕固定轴旋转。旋转量由指定的角度确定; 为正,旋转将为顺时针,为负,则为逆时针。
  • 值个数
    • 只有一个值,表示旋转的角度(单位 deg )
  • 值类型:
    • deg:<angle>类型,表示旋转角度(不是弧度)。
    • 正数为顺时针
    • 负数为逆时针
  • 简写:rotate3d(x, y, z, deg)
  • 注意:旋转的原点受 transform-origin 影响

1.2 rotate3d

  • 旋转:rotate3d(x, y, z, a)
    • 该 CSS 函数定义一个变换,它将元素围绕固定轴旋转。旋转量由指定的角度定义; 为正,运动将为顺时针,为负,则为逆时针。
  • 值个数
    • 一个值时,表示 z 轴 旋转的角度
    • 四个值时,表示在 3D 空间之中,旋转有 x , y , z 个旋转轴和一个旋转角度。
  • 值类型:
    • x:<number> 类型,可以是 0 到 1 之间的数值,表示旋转轴 X 坐标方向的矢量(用来计算形变矩阵中的值)。
    • y:<number> 类型,可以是 0 到 1 之间的数值,表示旋转轴 Y 坐标方向的矢量。
    • z:<number> 类型,可以是 0 到 1 之间的数值,表示旋转轴 Z 坐标方向的矢量。
    • a:<angle> 类型,表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转。
  • 注意:旋转的原点受 transform-origin 影响

1.3 rotateXYZ VS rotate3d

旋转函数,最终会生成一个4*4的矩阵

2. 3D透视

  • 透视:perspective
    • 定义了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果(z 表示Z 轴)。
    • z>0 的三维元素比正常的大,而 z<0 时则比正常的小,大小程度由该属性的值决定。
  • 值个数
    • 只有一个值,表示观察者距离 z=0 的平面距离 和 none
  • 必须是 <none><length> 中的一个
    • none:没有应用 perspective 样式时的默认值。
    • length:定观察者距离 z=0 平面的距离(如下图 d 的距离,单位 px)。
  • ✓ 为元素及其内容应用透视变换。当值为 0 或负值时,无透视变换。
  • 透视的两种使用方式:
    • 在父元素上定义 CSS 透视属性
    • 如果它是子元素或单元素子元素,可以使用函数 perspective()
  • 透视演练场:

3. 3D位移

3.1 translateX、translateY、translateZ

  • 平移:translateX(x)、translateY(y)、translateZ(z)
    • 该函数表示在二、三维平面上移动元素。
  • 值个数
    • 只有一个值,设置对应轴上的位移
  • 值类型:
    • 数字:100px
    • 百分比:参照元素本身( refer to the size of bounding box )

3.2 translate3d

  • 平移:translate3d(tx, ty, tz)
    • 该 CSS 函数在 3D 空间内移动一个元素的位置。这个移动由一个三维向量来表达,分别表示他在三个方向上移动的距离。
  • 值个数 三个值时,表示在 3D 空间之中, tx , ty , tz 分别表示他在三个方向上移动的距离。
  • 值类型:
    • tx:是一个 <length> 代表移动向量的横坐标。
    • ty:是一个 <length> 代表移动向量的纵坐标。
    • tz:是一个 <length> 代表移动向量的 z 坐标。它不能是 <percentage> 值;那样的移动是没有意义的。
  • 注意
    • translateX(tx)等同于 translate(tx, 0) 或者 translate3d(tx, 0, 0)。
    • translateY(ty) 等同于 translate(0, ty) 或者 translate3d(0, ty, 0)。
    • translateZ(zx) 等同于 translate3d(0, 0, tz)。

4. 3D缩放

4.1 scaleX、scaleY、scaleZ

  • 缩放:scaleX、scaleY、scaleZ
    • 函数指定了一个沿 x 、y 、z 轴调整元素缩放比例因子。
  • 值个数
    • 一个值时,设置对应轴上的缩放(无单位)
  • 值类型:
    • 数字:

      • ✓ 1:保持不变
      • ✓ 2:放大一倍
      • ✓ 0.5:缩小一半
    • 百分比:不支持百分比

4.2 scaleX、scaleY、scaleZ

  • 缩放:scale3d(sx, sy,sz)
    • 该 CSS 函数定义了在 3D 空间中调整元素的缩放比例因子 。。
  • 值个数
    • 三个值时,表示在 3D 空间之中, sx, sy, sz 分别表示他在三个方向上缩放的向量。
  • 值类型:
    • sx:是一个 <number> 代表缩放向量的横坐标。
    • sy:是一个 <number> 表示缩放向量的纵坐标。
    • sz:是 <number> 表示缩放向量的 z 分量的 a(再讲到 3D 正方体再演示)。
  • 注意
    • scaleX(sx) 等价于 scale(sx, 1) 或 scale3d(sx, 1, 1) 。
    • scaleY(sy) 等价于 scale(1, sy) 或 scale3d(1, sy, 1)。
    • scaleZ(sz) 等价于 scale3d(1, 1, sz)。

5. 3D空间

  • 变换式:transform-style
    • 该CSS属性用于设置元素的子元素是定位在 3D 空间中还是平展在元素的2D平面中。
    • 在3D空间中同样是可以使用透视效果。
  • 值类型:
    • flat:指示元素的子元素位于元素本身的平面内。
    • preserve-3d:指示元素的子元素应位于 3D 空间中。
  • 背面可见性:backface-visibility
    • 该CSS 属性 backface-visibility 指定某个元素当背面朝向观察者时是否可见。
  • 值类型:
    • visible:背面朝向用户时可见。
    • hidden:背面朝向用户时不可见。

6. 实例(制作一个骰子)

先将骰子的六个面绘制出来

html
<style>
  body {
    margin: 0;
    width: 100vw;
    height: 100vh;
    position: relative;
  }
  .dice-wrapper {
    position: relative;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 200px;
    height: 200px;
    display: flex;
    justify-content: space-around;
    align-items: center;
  }
  .dice-face {
    background-color: #fff;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border: 2px solid #000;
    border-radius: 10%;
    display: grid;
    place-items: center;
    grid-template: repeat(3, 1fr) / repeat(3, 1fr);
    grid-template-areas:
    "a . c"
    "e g f"
    "d . b";
  }

  .dot {
    display: inline-block;
    width: 50%;
    height: 50%;
    border-radius: 50%;
    background-color: #000;
  }

  .dot:nth-child(2) {
    grid-area: b;
  }

  .dot:nth-child(3) {
    grid-area: c;
  }

  .dot:nth-child(4) {
    grid-area: d;
  }

  .dot:nth-child(5) {
    grid-area: e;
  }

  .dot:nth-child(6) {
    grid-area: f;
  }

  .dot:nth-child(odd):last-child {
    grid-area: g;
  }
</style>

<body>
<div class="dice-wrapper">
  <div class="dice-face first-face">
    <span class="dot"></span>
  </div>
  <div class="dice-face second-face">
    <span class="dot"></span>
    <span class="dot"></span>
  </div>
  <div class="dice-face third-face">
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
  </div>
  <div class="dice-face fourth-face">
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
  </div>
  <div class="fifth-face dice-face">
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
  </div>
  <div class="dice-face sixth-face">
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
  </div>
</div>
</body>

.dice-wrapper稍作修改:

css
/* 在父元素中添加 transform-style来启用3D空间 */
.dice-wrapper {
    /*其他代码*/
    transform-style: preserve-3d;
    transform: rotateX(-33.5deg) rotateY(45deg);
}

此时效果如下:

接下来,我们调整一下六个面:

css
.first-face {
    transform: rotateX(90deg) translateZ(100px);
}
.second-face {
    transform: rotateX(-90deg) translateZ(100px);
}
.third-face {
    transform: rotateY(0deg) translateZ(100px);
}
.fourth-face {
    transform: rotateY(-180deg) translateZ(100px);
}
.fifth-face {
    transform: rotateY(-90deg) translateZ(100px);
}
.sixth-face {
    transform: rotateY(90deg) translateZ(100px);
}

最后,加个动画:

css
@keyframes boxLoop {
    0% {
        transform: rotateX(-33.5deg) rotateY(45deg);
    }
    50%,
    100% {
        transform: rotateX(-33.5deg) rotateY(405deg);
    }
}
.dice-wrapper {
    /* 添加旋转动画*/
    animation: boxLoop 4s linear infinite;
}
示例: ❐ 查看

参考资料与更多内容:

  1. CSS动画
  2. 菜鸟教程-CSS3动画