CSS理论实践之《动画》

436 阅读5分钟

基础知识

常见的css3动画一般有补间动画(又叫“关键帧动画”)和逐帧动画两种:

  1. 补间动画(关键帧动画): 自动完成从起始状态到终止状态的的过渡。不用管中间的状态。

常用于实现位移、颜色(透明度)、大小、旋转、倾斜等变化。一般有TransitionsKeyframes animation两种方法实现。

  • Transition:用于实现简单的动画,只有起始两帧过渡。多用于页面的交互操作,使交互效果更生动活泼。
  • Keyframes animation:用于实现较为复杂的动画,一般关键帧较多。animation的timing-function设置为easelinearcubic-bezier,它会在每个关键帧之间插入补间动画,产生具有连贯性的动画。
  1. 逐帧动画:通过一帧一帧的画面按照固定顺序和速度播放。如电影胶片。

逐帧动画可用于loading动画,但更多的用于Sprite精灵动画(人物运动)。精灵动画把所有帧都放在一起,通过CSS3的animation控制background-position

  • 关键帧之间的跳跃,animation的timing-function这时应该使用steps()过渡方式。

Transition

共有以下4个属性:

  1. transition-property: all; 如果希望所有的属性都发生过渡,就使用all。
  2. transition-duration: 1s;过渡的持续时间。
  3. transition-timing-function: linear;运动曲线。属性值可以是:
  • linear 线性
  • ease 减速
  • ease-in 加速
  • ease-out 减速
  • ease-in-out 先加速后减速
  1. transition-delay: 1s;过渡延迟。多长时间后再执行这个过渡动画。

简写形式: transition: 让哪些属性进行过度 过渡的持续时间 运动曲线 延迟时间 transition: all 3s linear 0s;

Keyframes animation

定义动画步骤:

  1. 通过@keyframes定义动画;
  2. 将这段动画通过百分比,分割成多个节点;然后各节点中分别定义各属性;
  3. 在指定元素里,通过 animation 属性调用动画。

animation的子属性有:

  • animation-name: 必填项,指定由@keyframes描述的关键帧名称。

  • animation-duration: 必填项,设置动画一个周期的时长。

  • animation-iteration-count: 设置动画重复次数, 可以指定infinite无限次重复动画。

  • animation-direction: 设置动画在每次运行完后是反向运行还是重新回到开始位置重复运行。normal 正常,alternate 反向。

  • animation-delay: 设置延时,即从元素加载完成之后到动画序列开始执行的这段时间。

  • animation-fill-mode: 指定动画执行前后如何为目标元素应用样式。forwards 保持动画结束后的状态(默认), backwards 动画结束后回到最初的状态。

  • animation-play-state: 允许暂停和恢复动画。

  • animation-timing-function: 设置动画速度, 即通过建立加速度曲线,设置动画在关键帧之间是如何变化。linearease-in-outsteps()等。

除了前两项必填且有先后顺序外,后面几个属性都是可选且是顺序无关的。如:

animation: move1 1s  alternate linear;
animation: move2 4s;

典型案例

进度条

loading-bar

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .div {
            margin: 20% auto;
            height: 10px;
            width: 300px;
            background: linear-gradient(#0ff, #0ff);
            background-repeat: no-repeat;
            background-size: 0;
            animation: move 2s linear forwards 3s;
        }

        @keyframes move {
            100% {
                background-size: 100%;
            }
        }
    </style>
</head>
<body>
<div class="div"></div>
</body>
</html>

打点loading效果

loading-dot

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .container {
            margin: 20% auto;
            text-align: center;
        }

        dot {
            display: inline-block;
            height: 1em;
            line-height: 1em;
            text-align: left;
            vertical-align: -.25em;
            overflow: hidden;
        }

        dot::before {
            display: block;
            content: '...\A..\A.';
            white-space: pre-wrap;
            animation: loading 3s infinite step-start both;
        }

        @keyframes loading {
            33% {
                transform: translateY(-2em);
            }
            66% {
                transform: translateY(-1em);
            }
        }
    </style>
</head>
<body>
<div class="container">
    正在加载中
    <dot>...</dot>
</div>
</body>
</html>

时钟

clock

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        div {
            width: 3px;
            height: 200px;
            background-color: #000;
            margin: 100px auto;
            transform-origin: center bottom;    /* 旋转的中心点是底部 */
            animation: myClock 60s steps(60) infinite;
        }

        @keyframes myClock {
            0% {
                transform: rotate(0deg);
            }

            100% {
                transform: rotate(360deg);
            }
        }
    </style>
</head>
<body>
<div></div>
</body>
</html>

环形进度条

loading-circle

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            display: flex;
            justify-content: center;
        }

        .circle_process {
            position: relative;
            width: 200px;
            height: 200px;
        }

        .circle_process .wrapper {
            width: 100px;
            height: 200px;
            position: absolute;
            top: 0;
            overflow: hidden;
        }

        .circle_process .right {
            right: 0;
        }

        .circle_process .left {
            left: 0;
        }

        .circle_process .circle {
            width: 160px;
            height: 160px;
            border: 20px solid transparent;
            border-radius: 50%;
            position: absolute;
            top: 0;
            transform: rotate(-135deg);
        }

        .circle_process .right-circle {
            border-top: 20px solid green;
            border-right: 20px solid green;
            right: 0;
            animation: right-turn 5s linear infinite;
            /*animation-name: circle_right; //动画名称
            animation-duration: 5s;  //完成一个动画需要的时间
            animation-timing-function: linear;  //动画播放的方式,linear是匀速变化
            animation-iteration-count: infinite;  //动画播放的次数,infinite是无限次数 */
        }

        .circle_process .left-circle {
            border-bottom: 20px solid green;
            border-left: 20px solid green;
            left: 0;
            animation: left-turn 5s linear infinite;
        }

        @keyframes right-turn {
            0% {
                transform: rotate(-135deg);
            }
            50%, 100% {
                transform: rotate(45deg);
            }
        }

        @keyframes left-turn {
            0%, 50% {
                transform: rotate(-135deg);
            }
            100% {
                transform: rotate(45deg);
            }
        }
    </style>
</head>
<body>
<div class="circle_process">
    <div class="wrapper right">
        <div class="circle right-circle"></div>
    </div>
    <div class="wrapper left">
        <div class="circle left-circle"></div>
    </div>
</div>
</body>
</html>