6. anothers

6.1 transition

transition mdn

transition CSS 属性是 transition-property,transition-duration,transition-timing-function 和 transition-delay 的一个简写属性。

6.2 cubic-bezier

cubic-bezier mdn

B(t) = P₀(1 - t)³ + 3P₁t(1 - t)² + 3P₂t²(1 - t) + P₃t³ ,t ∈ [0,1]

  1. 这是三次贝塞尔曲线的函数
  2. P P 分别表示起点和终点
  3. P P 表示的是两个控制点 (n 次贝塞尔曲线 n-1 个控制点)

6. 动画、过渡等 - 图1

6. 动画、过渡等 - 图2

cubic-bezier 是 transition-timing-function 属性的属性值
transition-timing-function 的属性值 如上表所示 也可以是关键字 但实际上 它们都有对应的 cubic-bezier 取值

它们实质上都是设置 过渡动画 的运动效果 这个运动效果我们也可以在控制台微调

6. 动画、过渡等 - 图3

1 表示 过渡动画 的运动效果
2 表示 cubic-bezier 的取值
P0 和 P3 是起点 (0, 0) 和 (1, 1)
P1 和 P2 是两个控制点(可拖拽) 它们的坐标是 cubic-bezier 的值 即: P1 (0.43, -0.27) P2 (0.54, 1.34)

只要将我们设置好的 cubic-bezier 的值复制到 transition-timing-funtion 中即可, 也就是 transition 的第三个属性值
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>cubic-bezier</title>
    <style>
        div {
            border: 1px solid #f40;
            border-radius: 10px;

            width: 100px;
            height: 50px;

            transition: all 1s cubic-bezier(0.43, -0.27, 0.54, 1.34);
        }

        div:hover {
            width: 500px;
        }
    </style>
</head>

<body>
    <div></div>
</body>

</html>

6. 动画、过渡等 - 图4

当鼠标悬停上去的时候, 它首先会收缩一部分(小于 100px), 然后再伸, 并且会伸过头一部分(大于 500px), 最后再停留到设定值 500px

6.3 animation

transition 实现的过渡动画 仅能在两个状态之间来回切换 但是 animation 可以实现多个状态的动画

animation mdn

animation: name duration timing-function delay iteration-count direction fill-mode play-state;

6. 动画、过渡等 - 图5

notes
    1. animation-timing-function 设置的是每一个状态切换的运动效果 而非一个完整动画的运动效果; (每一个状态切换的运动效果都一样 若想让它们不一样 可以借助 js 来实现)
    2. animation-delay 设置的是一个完整动画的延时 而非 每一个状态切换的延时;
    3. animation-play-state 兼容性不好 基本也用不到
    4. animation-fill-mode 可以设置动画的状态
       forwards 运动结束后 保留最后一帧的状态
       backwards 运动开始前 显示第一帧的状态
       both 就是 forwards + backwards
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>animation</title>
    <style>
        .box {
            position: absolute;
            top: 0;
            left: 0;

            border-radius: 50%;
            width: 100px;
            height: 100px;
            background-color: #008c8c;
            cursor: pointer;

            animation: run 4s, color-change 4s; /* 4s 指动画的总时长 */
        }

        /* @keyframes 关键帧容器
        run 关键帧容器的 名称 */
        @keyframes run {
            0%{ /* 0% 也可以写成 from */
                left: 0;
                top: 0;
            } /* 注意 多个运动状态之间 不需要添加 逗号 作为分隔 */
            25%{ /* 当动画的运动时长达到总时长的 25% 时 的状态值 */
                left: 100px;
                top: 0;
            }
            50%{
                left: 100px;
                top: 100px;
            }
            75%{
                left: 0;
                top: 100px;
            }
            100%{ /* 100% 也可以写成 to */
                left: 0;
                top: 0;
            }
        }

        @keyframes color-change {
            from {
                background-color: red;
            }
            50% {
                background-color: green;
            }
            to {
                background-color: blue;
            }
        }
    </style>
</head>

<body>
    <div class="box"></div>
</body>

</html>
notes
    当动画结束后, 元素的状态 默认 会回归到动画开始前的状态;
    可以同时给一个元素添加多个动画;

6.4 animation2

日升日落 月升月落 效果

6.5 step

timing-function mdn

steps() 定义了一个以等距步长划分值域的步长函数。
这个阶跃函数的子类有时也称为阶梯函数。

steps 和 cubic-bezier 一样 都是 timing-function 的属性值

notes
    end 保留当前帧状态, 直到这段动画时间结束 (默认值)
        解决最后一帧直接跳过的问题:
           animation: animation-name steps (num, end) forwards; /* forwards 用于保留最后一帧的状态 */
    start 保留下一帧状态, 直到这段动画时间结束
        注意: 第一帧的跳过无法使用 backwords 来解决 因为动画开始的时刻就是一个时间点 (同样的道理 若steps的第二个参数是 end 当这个动画运动次数为 infinite 时 那么最后一帧也会变为一个时间点 我们是否设置 forwards 属性 都不影响)
    steps(1, end) === step-end
    steps(1, start) === step-start

end 和 start

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>steps</title>
    <style>
        @keyframes run {
            from {
                left: 0px;
            }

            20% {
                left: 50px;
            }

            40% {
                left: 100px;
            }

            60% {
                left: 150px;
            }

            80% {
                left: 200px;
            }

            to {
                left: 250px;
            }
        }

        .demo1,
        .demo2 {
            position: absolute;

            border-radius: 50%;

            width: 100px;
            height: 100px;
            line-height: 100px;
            text-align: center;
            color: #fff;
            background-color: #008c8c;
        }

        .demo1 {
            animation: run 5s steps(1, end) forwards;
            /* animation: run 5s steps(1, end) infinite forwards; */
        }

        .demo2 {
            top: 150px;
            animation: run 5s steps(1, start);
        }
    </style>
</head>

<body>
    <div class="demo1">end</div>
    <div class="demo2">start</div>
</body>

</html>

6.6 step2

打字效果
钟表效果
跑马效果

6.7 rotate

rotate mdn)

6. 动画、过渡等 - 图6

rotate3d mdn)

perspective mdn

transform-style mdn

perspective-origin mdn

图片前后来回摆动效果

6.8 scale

scale mdn)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>scale</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        div {
            position: absolute;
            top: 100px;
            left: 100px;

            border: 1px solid;
            box-sizing: border-box;
            height: 100px;
            width: 100px;
        }

        .demo1 {
            border-color: #008c8c;
        }

        .demo2 {
            border-color: #f40;
        }
    </style>
</head>

<body>
    <div class="demo1"></div>
    <div class="demo2"></div>
</body>

</html>

6. 动画、过渡等 - 图7

注意点1:
    scale 缩放的并非元素的大小 而是 坐标轴的刻度

6. 动画、过渡等 - 图8

6. 动画、过渡等 - 图9

6. 动画、过渡等 - 图10

注意点2:
    scale 可以实现叠加操作

6. 动画、过渡等 - 图11

6. 动画、过渡等 - 图12

注意点3:
    伸缩和旋转的顺序不同 可能会导致结果也不同

6. 动画、过渡等 - 图13

6. 动画、过渡等 - 图14

scaleZ 不易于演示

6.9 skew

skew mdn)

注意点1
    skew 不仅具有倾斜效果 还具有拉伸效果

6. 动画、过渡等 - 图15

注意点2
    skew 和 scale 一样 改变的都是坐标轴
    若先操作了 skew 那么也会对后续有关坐标轴的操作造成影响

6. 动画、过渡等 - 图16

6. 动画、过渡等 - 图17

6.10 translate+perspective

未知尺寸元素的居中问题

/* 在自身的宽高不确定的前提下 若依旧想令该元素水平垂直居中 */
selector {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

perspective mdn

perspective 表示 景深 (可叠加)
    作用
        用于增强 3d 效果
    使用
       设置在父级上 (单人视角 一双眼睛)
          perspective: 800px;
          全局 一个 景深
          可以调节 origin 的值
          常用
       设置在每一个子元素上 (多人视角 多双眼睛)
          transform: perspective(800px); /* 注意 若不写在最前面 有一些浏览器就识别不了 */
          每一个子元素都有对应的 景深
          不能调节 origin 的值
          不常用

perspective-origin mdn

6. 动画、过渡等 - 图18

用户所能看到的物体的大小 实际上是该物体在屏幕上投影的大小

demos perspective-1

transform-style mdn

transform-style 该属性要设置在直接父级上

照片旋转效果

6.11 perspective2

backface-visibility mdn

3D 旋转照片墙

6.12 matrix

matrix mdn)

matrix 矩阵计算规则 transform

矩阵的计算规则: 第一个矩阵的行 * 第二个矩阵的列
    | a, c, e |   | x |   | ax + cy + e |
    | b, d, f | * | y | = | bx + dy + f |
    | 0, 0, 1 |   | 1 |   | 0  + 0  + 1 |
参数说明:
    matrix (a, b, c, d, e, f)
    (x, y) 是变化元素上的每一个像素点的坐标
    结果矩阵就是经过 transform 变化之后的元素各像素点的坐标

eg:
    1. transform: translate(n, m); === transform: matrix(1, 0, 0, 1, n, m)
          | 1, 0, n |   | x |   | x + 0 + n |
          | 0, 1, m | * | y | = | 0 + y + m |
          | 0, 0, 1 |   | 1 |   | 0 + 0 + 1 |
       transform 之前 元素身上的所有像素点的坐标值是 (x, y)
       经过 transform: translate(n, m); 变化之后
       坐标变为 (x + n, y + m)
       notes:
          (1, 0, 0, 1, n, m) 这 6 个值是倒推出来的结果
    2. transform: scale(n, m); === transfor: matrix(n, 0, 0, m, 0, 0)
          | n, 0, 0 |   | x |   | nx + 0  + 0 |
          | 0, m, 0 | * | y | = | 0  + my + 0 |
          | 0, 0, 1 |   | 1 |   | 0  + 0  + 1 |
       原理: 同1
    3. rotate(θ) === matrix(cos(θ), sin(θ), -sin(θ), cos(θ), 0, 0)
    ...
PS: 上面介绍的仅仅是 transform 的二维变化原理 三维变化实际上原理也相同 也是通过矩阵来计算的 不过暂时没有研究的必要
利用掌握的 matrix 原理 实现图片的 左右翻转效果
思路:
    (x, y) -> (-x, y)

    | a, c, e |   | x |   | ax + cy + e |
    | b, d, f | * | y | = | bx + dy + f |
    | 0, 0, 1 |   | 1 |   | 0  + 0  + 1 |

    matrix (a, b, c, d, e, f);

    a 是 -1
    d 是 1
    其余都是 0

    matrix (-1, 0, 0, 1, 0, 0);
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>matrix</title>
    <style>
        body {
            background-color: #ddd;
        }

        div {
            position: absolute;
            top: 50%;
            left: 50%;
            /* 图片正常展示效果 */
            transform: translate(-50%, -50%);
            /* 图片水平翻转后的展示效果 */
            /* transform: translate(-50%, -50%) matrix(-1, 0, 0, 1, 0, 0); */

            width: 200px;
            height: 200px;
            background-image: url(./img/dahuyou.jpg); /* 路径也许会有误 得修改 */
            background-size: cover;
        }
    </style>
</head>

<body>
    <div></div>
</body>

</html>

6. 动画、过渡等 - 图19

6. 动画、过渡等 - 图20