变形介绍

  1. 变形效果要通过变形函数来实现,语法如下:

    transform: none | transform-functions;
    
  2. 那么 CSS3 中提供了哪些变形函数呢?整体可以划分出 3 大类:

    • 具有 X/Y 的函数:translateX、translateY、sclaeX、scaleY、skewX、skewY
    • 2D 变形函数:translate、sclae、rotate、skew、matrix
    • 3D 变形函数:rotateX、rotateY、rotate3d、translateZ、translate3d、scaleZ、scale3d、matrix3d
  3. matrix、matrix3d 比较复杂,一般借助于 库函数 来实现复杂效果;

变形属性

transform-origin 属性

  1. transform-origin 属性用于设置元素的中心点位置,变换的原点默认在元素的中心点;

  2. 语法

    transform-origin: x-axis y-axis z-axis;
    
  3. 属性值

    描述
    x-axis 定义视图被置于 X 轴的何处,可能的值
    1. left
    2. center
    3. right
    4. length
    5. %
    y-axis 定义视图被置于 Y 轴的何处,可能的值
    1. top
    2. center
    3. bottom
    4. length
    5. %
    z-axis 定义视图被置于 Z 轴的何处,可能的值
    1. length
  4. 示例

    <style>
    #origin1 {
      width: 150px;
      height: 150px;
      background-color: red;
      margin: 200px;
      transition: all 1s;
    }
    #origin1:hover {
      transform: rotate(45deg);
    }
    
    #origin2 {
      width: 150px;
      height: 150px;
      background-color: red;
      margin: 200px;
      transition: all 1s;
      transform-origin: bottom left;
      /* 修改元素的中心点位置 */
    }
    #origin2:hover {
      transform: rotate(45deg);
    }
    </style>
    
    <div id="origin1"></div>
    <div id="origin2"></div>
    

transform-style 属性

  1. transform-style 属性是 3D 空间一个重要属性,指定了嵌套元素如何在 3D 空间中呈现

  2. 语法

    transform-style: flat | preserve-3d;
    
  3. 属性值

    描述
    flat(默认值) 表示所有子元素在 2D 平面 呈现
    preserve-3d 表示所有子元素在 3D 空间 呈现
  4. 示例

    <style>
        .box {
            width: 250px;
            height: 250px;
            border: 1px dashed red;
            margin: 50px 100px;
            position: relative;
            border-radius: 50%;
            animation: gun 8s linear infinite;
        }
    
        .box1 {
            transform-style: preserve-3d;
        }
    
        .box2 {
            transform-style: flat;
        }
    
        .box>div {
            width: 100%;
            height: 100%;
            position: absolute;
            text-align: center;
            line-height: 250px;
            font-size: 60px;
            color: #daa520;
        }
    
        .left {
            background-color: rgba(255, 0, 0, 0.3);
            transform-origin: left;
            transform: rotateY(90deg) translateX(-125px);
        }
    
        .right {
            background: rgba(0, 0, 255, 0.3);
            transform-origin: right;
            /* 变换*/
            transform: rotateY(90deg) translateX(125px);
        }
    
        .forward {
            background: rgba(255, 255, 0, 0.3);
            transform: translateZ(125px);
        }
    
        .back {
            background: rgba(0, 255, 255, 0.3);
            transform: translateZ(-125px);
        }
    
        .up {
            background: rgba(255, 0, 255, 0.3);
            transform: rotateX(90deg) translateZ(125px);
        }
    
        .down {
            background: rgba(99, 66, 33, 0.3);
            transform: rotateX(-90deg) translateZ(125px);
        }
    
        @keyframes gun {
            0% {
                transform: rotateX(0deg) rotateY(0deg);
            }
    
            100% {
                transform: rotateX(360deg) rotateY(360deg);
            }
        }
    </style>
    <div style="display: flex;">
        <div class="box box1">
            <div class="up">上</div>
            <div class="down">下</div>
            <div class="left">左</div>
            <div class="right">右</div>
            <div class="forword">前</div>
            <div class="back">后</div>
        </div>
        <div class="box box2">
            <div class="up">上</div>
            <div class="down">下</div>
            <div class="left">左</div>
            <div class="right">右</div>
            <div class="forword">前</div>
            <div class="back">后</div>
        </div>
    </div>
    

perspective 属性

  1. perspective 属性用于设置查看者的位置,可以将可视内容映射到一个视锥上,继而投到一个 2D 视平面上;如果不指定该属性,则 Z 轴空间中所有点将平铺到同一个 2D 视平面中,并且在变换结果中将不存在景深概念;

  2. 简单理解,就是视距,用来设置用户和元素 3D 空间 Z 平面之间的距离;而其效应由他的值来决定,值越小,用户与 3D 空间 Z 平面距离越近,视觉效果更令人印象深刻;反之,值越大,用户与 3D 空间 Z 平面距离越远,视觉效果就很小;

  3. 注意当为元素定义 perspective 属性时,其子元素会获得透视效果,而不是元素本身;

  4. 关于 perspective 的取值,接受一个长度单位大于 0 ,其单位不能为百分比的值;大致能够分为如下 3 种情况:

    描述
    none 或者不设置 没有 3D 空间
    取值越小 3D 效果越明显,也就是眼睛越靠近真 3D
    取值无穷大或者为 0 与取值为 none 的效果一样
  5. 示例

    <style>
        .container {
            width: 300px;
            height: 200px;
            display: flex;
            justify-content: center;
            align-items: center;
        }
    
        .container1 {
            perspective: 1200px;
        }
    
        .item {
            width: 150px;
            height: 150px;
            background-color: red;
            animation: rotateAnimation 5s infinite;
        }
    
        @keyframes rotateAnimation {
            0% {
                transform: rotateY(0deg);
            }
    
            100% {
                transform: rotateY(360deg);
            }
        }
    </style>
    <div style="display: flex;">
        <div class="container">
            <div class="item"></div>
        </div>
        <div class="container container1">
            <div class="item"></div>
        </div>
    </div>
    

perspective-origin 属性

  1. 如果理解了上面的 perspective 属性,那么这个 perspective-origin 就非常好理解了,该属性用来决定 perspective 属性的源点角度;

  2. 其语法如下:

    perspective-origin: x-axis y-axis;
    
  3. x-axisy-axis 取值

    描述
    x-axis 定义视图在 X 轴的位置,默认值 50%
    1. left
    2. center
    3. right
    4. length
    5. %
    y-axis 定义视图在 Y 轴的位置,默认值 50%
    1. top
    2. center
    3. bottom
    4. length
    5. %
  4. 示例

    <style>
        .container {
            width: 300px;
            height: 200px;
            display: flex;
            justify-content: center;
            align-items: center;
            perspective: 500px;
        }
    
        .container1 {
            perspective-origin: top;
        }
        .container2 {
            perspective-origin: bottom;
        }
    
        .item {
            width: 150px;
            height: 150px;
            background-color: red;
            animation: rotateAnimation 5s infinite;
        }
    
        @keyframes rotateAnimation {
            0% {
                transform: rotateY(0deg);
            }
    
            100% {
                transform: rotateY(360deg);
            }
        }
    </style>
    <div style="display: flex;">
        <div class="container container1">
            <div class="item"></div>
        </div>
        <div class="container container2">
            <div class="item"></div>
        </div>
    </div>
    

backface-visibility 属性

  1. backface-visibility 属性决定元素旋转背面是否可见;对于未旋转的元素,该元素的正面面向观看者;当其旋转 180 度时会导致元素的背面面向观众;

  2. 该属性是设置在旋转的元素上面,语法如下:

    backface-visibility: visible | hidden;
    
  3. 来看一个具体的例子:

    <style>
        .container {
            width: 300px;
            height: 200px;
            display: flex;
            justify-content: center;
            align-items: center;
            perspective: 500px;
        }
    
        .item1 {
            backface-visibility: visible;
        }
        .item2 {
            backface-visibility: hidden;
        }
    
        .item {
            width: 150px;
            height: 150px;
            background-color: red;
            animation: rotateAnimation 5s infinite;
        }
    
        @keyframes rotateAnimation {
            0% {
                transform: rotateY(0deg);
            }
    
            100% {
                transform: rotateY(360deg);
            }
        }
    </style>
    <div style="display: flex;">
        <div class="container">
            <div class="item item1"></div>
        </div>
        <div class="container">
            <div class="item item2"></div>
        </div>
    </div>
    

2D 变形

2D 位移

  1. 2D 位移对应有 3 个变形函数,分别是 translatetranslateXtranslateY

  2. 示例

    <style>
        #translate2D {
            width: 150px;
            height: 150px;
            background-color: red;
            margin: 50px;
            transition: all 1s;
        }
    
        #translate2D:hover {
            transform: translate(100px, 20px);
        }
    </style>
    <div id="translate2D"></div>
    

2D 缩放

  1. 2D 缩放对应的也有 3 个变形函数,分别是 sclaesclaeXsclaeY

  2. 示例

    <style>
        #sclae2D {
            width: 150px;
            height: 150px;
            background-color: red;
            margin: 50px;
            transition: all 1s;
        }
    
        #sclae2D:hover {
            transform: sclae(3, 1.5);
        }
    </style>
    <div id="sclae2D"></div>
    

2D 旋转

  1. 2D 旋转对应的只有 1 个变形函数 rotate ,该变形函数只接受一个值代表旋转的角度值,取值可正可负,正值代表顺时针旋转,负值代表逆时针旋转;

  2. 示例

    <style>
        #rotate2D {
            width: 150px;
            height: 150px;
            background-color: red;
            margin: 50px;
            transition: all 1s;
        }
    
        #rotate2D:hover {
            transform: rotate(90deg);
        }
    </style>
    <div id="rotate2D"></div>
    

2D 倾斜

  1. 2D 倾斜对应的变形函数也是 3 个,分别是 skewskewXskewY

  2. 示例

    <style>
        #skew2D {
            width: 150px;
            height: 150px;
            background-color: red;
            margin: 50px;
            transition: all 1s;
        }
    
        #skew2D:hover {
            transform: skew(20deg, 20deg);
        }
    </style>
    <div id="skew2D"></div>
    

2D 矩阵

  1. 虽然 CSS3 提供了上述的变形函数方便我们进行元素的变形操作,但是毕竟函数个数有限,有些效果是没有提供的,例如镜像翻转的效果;此时就轮到 2D 矩阵函数 matrix 登场了,matrix 有六个参数:

    matrix(a, b, c, d, e, f);
    
  2. 六个参数对应的矩阵:

  3. 这六个参数组成的矩阵与原坐标矩阵相乘计算坐标,计算方式如下:

  4. 什么意思呢?

    • xy 是元素中每一个像素的初始原点的坐标,而 x’y’ 是通过矩阵变化后得到的新原点坐标;
    • 通过中间 3 x 3 变换矩阵,对原先的坐标施加变换,从而得到新的坐标;
    • x' = ax + cy + e 表示变换后的 水平 坐标;
    • y' = bx + dy + f 表示变换后的 垂直 位置;
  5. CSS3 中,上面介绍的所有 2D 变形函数都能够通过这个 matrix 矩阵函数来替代;

    • 矩阵实现偏移
    /*
      1. 偏移效果前后 x、y 与 x'、y' 所对应的坐标公式为:
          x' = x + 偏移量
          y' = y + 偏移量
      2. 套用上面的公式那么各个参数的取值就应该是:
          a = 1; b = 0; c = 0; d = 1;
          e = x 偏移量; f = y 偏移量
    
          x' = ax+cy+e = 1x + 0y + x 偏移量 = x + x 偏移量
          y' = bx+dy+f = 0x + 1y + y 偏移量 = y + y 偏移量
      3. 所以换成 *matrix* 函数就应该是:
          matrix(1, 0, 0, 1, x 偏移量, y 偏移量)
          等价
          transform: translate(x 偏移量, y 偏移量);
    */
    
    • 矩阵实现缩放
    /*
      1. 缩放之后  x、y 与 x'、y' 所对应的坐标公式为:
          x' = x * x 缩放倍数
          y’ = y * y 缩放倍数
      2. 套用上面的公式那就是:
          a = x缩放倍数; b = 0; c = 0; d = y 缩放倍数; e = 0; f = 0;
    
          x' = ax+cy+e = x缩放倍数 * x + 0y + 0 = x缩放倍数 * x
          y' = bx+dy+f = 0x + y 缩放倍数 * y + 0 = y 缩放倍数 * y
      3. 所以换成 matrix 函数就应该是:
          matrix(x 缩放倍数, 0, 0, y 缩放倍数, 0, 0);
          等价
          transform: scale(x 缩放倍数, y 缩放倍数);
    */
    
    • 矩阵实现旋转
    /*
      1. 旋转需要实现 =>  水平倾斜角度 =  - 垂直倾斜角度
      2. 旋转用到的变形函数是 rotate(θ),其中 **θ** 为旋转的角度,套用上面的公式:
          x' = xcosθ - ysinθ + 0 = xcosθ - ysinθ;
          y' = xsinθ + ycosθ + 0 = xsinθ + ycosθ
      3. 转换为 *matrix* 的代码为:
          matrix(cos(θ), sin(θ), -sin(θ), cos(θ), 0, 0)
          例如:
              transform: rotate(45deg);
              等价
              transform: matrix(0.7, 0.7, -0.7, 0.7, 0, 0);
    */
    
    • 矩阵实现倾斜
    /*
    1. skew(θx, θy) 将一个元素按指定的角度在 X 轴和 Y 轴上倾斜,倾斜对应的公式为:
        x' = x + ytan(θx) + 0 = x + ytan(θx)
        y' = xtan(θy) + y + 0 = xtan(θy) + y
    2. 转换为 matrix 的代码为:
        matrix(1, tan(θy), tan(θx), 1, 0, 0)
        例如
          transform: skew(20deg);
          等价
          transform: matrix(1, 0.4, 0.4, 1, 0, 0);
    */
    
    • 矩阵实现水平镜像变形
    /*
      1. 水平镜像,就是 y 坐标不变,x 坐标变负
          x' = -x;
          y' = y;
      2. 所以:
          a = -1; b = 0;  c = 0; d = 1; e = 0; f = 0;
      3. 转换为 matrix 的代码为:
          transform: matrix(-1, 0, 0, 1, 0, 0);
    */
    
    • 矩阵实现垂直镜像变形
    /*
      1. 垂直镜像,就是 x 坐标不变,y 坐标变负
          x' = x;
          y' = -y;
      2. 所以:
          a = 1; b = 0;  c = 0; d = -1;  e = 0; f = 0;
      3. 转换为 matrix 的代码为:
          transform: matrix(1, 0, 0, -1, 0, 0);
    */
    

3D 变形

  1. 使用二维变形能够改变元素在水平和垂直轴线,然而还有一个轴沿着它,可以改变元素;使用三维变形,可以改变元素在 Z 轴位置;

  2. 三维变换使用基于二维变换的相同属性,如果熟悉二维变换就会发现,3D 变形的功能和 2D 变换的功能类似;CSS3 中的 3D 变换只要包含以下几类:

    • 3D 位移:包括 translateZtranslate3d 两个变形函数;
    • 3D 旋转:包括 rotateX、rotateY、rotateZrotate3d 这四个变形函数;
    • 3D 缩放:包括 scaleZsclae3d 两个变形函数;
    • 3D 矩阵:和 2D 变形一样,也有一个 3D 矩阵功能函数 matrix3d

3D 位移

  1. translate3d 语法如下:

    /*
     * tx:在 X 轴的位移距离;
     * ty:在 Y 轴的位移距离;
     * tz:在 Z 轴的位移距离;值越大,元素离观察者越近,值越小,元素离观察者越远
     */
    translate3d(tx, ty, tz);
    
  2. 来看一个具体的示例:

    <style>
        .container-3d {
            width: 400px;
            height: 100px;
            margin: 50px;
            display: flex;
            align-items: center;
            perspective: 1000px;
        }
    
        .container-3d-item {
            width: 300px;
            height: 200px;
            transition: all 1s;
            background: url('/article/c03b1f28/meimei.png') no-repeat;
            background-position: center;
            background-size: contain;
        }
    
        .container-3d-item:hover {
            transform: translate3d(100px, -100px, -500px)
        }
    </style>
    <div class="container-3d">
        <div class="container-3d-item"></div>
    </div>
    

3D 缩放

  1. 3D 缩放主要有 sclaeZscale3d ,其中 scale3d 就是 scaleXscaleY 以及 scaleZ 的复合变形函数;

  2. 语法如下:

    /*
     * sx:X 轴上的缩放比例
     * sy:Y 轴上的缩放比例
     * sz:Z 轴上的缩放比例
     */
    scale(sx, sy, sz)
    
  3. scaleXscaleY 变形效果很明显,但是 scaleZ 却基本看不出有什么效果;原因很简单,scaleZZ 轴上面的缩放,也就是厚度上面的变化,所以如果不是立方体结构,基本上是看不出来 Z 轴上面的缩放效果的;

  4. 一般不会将 scaleZscale3d 单独使用,因为 scaleZscale3d 这两个变形函数在单独使用时没有任何效果,需要配合其他的变形函数一起使用时才会有效果;

    <style>
        .box-3d-scale {
            width: 250px;
            height: 250px;
            border: 1px dashed red;
            margin: 50px;
            position: relative;
            border-radius: 50%;
            transform-style: preserve-3d;
            transition: all 1s;
            transform: rotateX(45deg) rotateY(45deg);
        }
    
        .box-3d-scale:hover {
            transform: rotateX(45deg) rotateY(45deg) scaleZ(.5);
        }
    
        .box-3d-scale>div {
            width: 100%;
            height: 100%;
            position: absolute;
            text-align: center;
            line-height: 250px;
            font-size: 60px;
            color: #daa520;
        }
    
        .box-3d-scale-left {
            background-color: rgba(255, 0, 0, 0.3);
            transform-origin: left;
            transform: rotateY(90deg) translateX(-125px);
        }
    
        .box-3d-scale-right {
            background: rgba(0, 0, 255, 0.3);
            transform-origin: right;
            /* 变换*/
            transform: rotateY(90deg) translateX(125px);
        }
    
        .box-3d-scale-forward {
            background: rgba(255, 255, 0, 0.3);
            transform: translateZ(125px);
        }
    
        .box-3d-scale-back {
            background: rgba(0, 255, 255, 0.3);
            transform: translateZ(-125px);
        }
    
        .box-3d-scale-up {
            background: rgba(255, 0, 255, 0.3);
            transform: rotateX(90deg) translateZ(125px);
        }
    
        .box-3d-scale-down {
            background: rgba(99, 66, 33, 0.3);
            transform: rotateX(-90deg) translateZ(125px);
        }
    </style>
    <div class="box-3d-scale">
        <div class="box-3d-scale-up">上</div>
        <div class="box-3d-scale-down">下</div>
        <div class="box-3d-scale-left">左</div>
        <div class="box-3d-scale-right">右</div>
        <div class="box-3d-scale-forword">前</div>
        <div class="box-3d-scale-back">后</div>
    </div>
    

3D 旋转

  1. 在三维变形中,可以让元素在任何轴旋转,对应的变形函数有 rotateX、rotateY、rotateZ 以及 rotate3d;其中 rotate3d 就是前面 3 个变形函数的复合函数

    rotate3d(x, y, z, a)
    
  2. 不过出了 x、y、z 这三条轴的参数以外,还接受第四个参数 a,表示旋转角度;

    • x:可以是 01 之间的数值,表示旋转轴 X 坐标方向的矢量;
    • y:可以是 01 之间的数值,表示旋转轴 Y 坐标方向的矢量;
    • z:可以是 01 之间的数值,表示旋转轴 Z 坐标方向的矢量;
    • a:表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转;
  3. 示例:

    <style>
      .container-3d-rotate{
        width: 300px;
        height: 150px;
        margin: 50px;
        display: flex;
        justify-content: center;
        align-items: center;
        perspective: 1000px;
      }
      .container-3d-rotate-item {
        width: 150px;
        height: 150px;
        background-color: red;
        transition: all 1s;
      }
      
      .container-3d-rotate-item:hover {
        transform: rotate3d(0.5, 0, 1, 90deg)
      }
    </style>
    <div class="container-3d-rotate">
      <div class="container-3d-rotate-item"></div>
    </div>
    

3D 矩阵

  1. CSS3 中的 3D 矩阵比 2D 矩阵复杂,从二维到三维,在矩阵里 3 * 3 变成 4 * 4 ,即 916

  2. 对于 3D 矩阵而言,本质上很多东西与 2D 是一致的,只是复杂程度不一样而已,对于 3D 缩放效果,其矩阵如下:

  3. 对应的公式如下:

    matrix3d(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
    
  4. 倾斜是二维变形,不能在三维空间变形。元素可能会在 X 轴和 Y 轴倾斜,然后转化为三维,但它们不能在 Z 轴倾斜;

  5. 这里举几个 3D 矩阵的例子:

    • translate3d(tx, ty, tz) 等价于 matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1)

    • scale3d(sx, sy, sz) 等价于 matrix3d(sx , 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1)

    • rotate3d(x, y, z, a) 第四个参数 alpha 用于 scsq

面试题

请简述 CSS3 中新增的变形如何使用?

  1. CSS3 中的变形分为 2D 变形和 3D 变形;

  2. 整体可以划分出 3 大类:

    • 具有 X/Y 的函数:translateX、translateY、sclaeX、scaleY、skewX、skewY
    • 2D 变形函数:translate、sclae、rotate、skew、matrix
    • 3D 变形函数:rotateX、rotateY、rotate3d、translateZ、translate3d、scaleZ、scale3d、matrix3d
  3. 另外,还有一些重要的变形属性,例如:

    • transform 属性
    • transform-origin 属性
    • transform-style 属性
    • perspective 属性
    • perspective-origin 属性
    • backface-visibility 属性
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 变形介绍
  2. 2. 变形属性
    1. 2.1. transform-origin 属性
    2. 2.2. transform-style 属性
    3. 2.3. perspective 属性
    4. 2.4. perspective-origin 属性
    5. 2.5. backface-visibility 属性
  3. 3. 2D 变形
    1. 3.1. 2D 位移
    2. 3.2. 2D 缩放
    3. 3.3. 2D 旋转
    4. 3.4. 2D 倾斜
    5. 3.5. 2D 矩阵
  4. 4. 3D 变形
    1. 4.1. 3D 位移
    2. 4.2. 3D 缩放
    3. 4.3. 3D 旋转
    4. 4.4. 3D 矩阵
  5. 5. 面试题
    1. 5.1. 请简述 CSS3 中新增的变形如何使用?