Skip to content

动画学习

transition

运用transform可以使元素动起来,但是会显得有点抖动,配合上transition会更加平滑:

让我们先定义一个按钮,然后再为按钮写一点css,这时候当鼠标移动到按钮上就会进行向上的移动,但是按钮移动的太快。

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>
    <link rel="stylesheet" href="./style.css">
</head>

<body>
    <button class="btn">learn more</button>
</body>

</html>
css
:root{
    --clr-accent:#08a9c6;
    --clr-rgba:#c9f2fc;
}

body{
    display: flex;
    height: 100vh;
    justify-content: center;
    align-items: center;
    overflow: hidden;
}

.btn{
    font-size: 2rem;
    font-weight: 700;
    padding: 0.5em 1em;
    color:var(--clr-accent);
    background-color: var(--clr-rgba);
    border: 10px solid var(--clr-accent);
    border-radius: 5px;
}

.btn:hover{
    transform: translateY(-10px);
}

css配合上transition:

css
.btn{
    font-size: 2rem;
    font-weight: 700;
    padding: 0.5em 1em;
    color:var(--clr-accent);
    background-color: var(--clr-rgba);
    border: 10px solid var(--clr-accent);
    border-radius: 5px;

    /* 动画过渡属性 */
    transition-property: transform;
    /* 动画过渡持续时间 */
    transition-duration: 0.3s;
    /* 动画过渡计时函数,过渡的加速曲线 */
    transition-timing-function: ease;
    /* 动画过渡延迟 */
    transition-delay: 0s;
}

这时候按钮的向上移动就会显得很平滑。

以上四种transition属性一般简写为transition: transform 0.3s ease 0s;


我们还可以变换一下背景和字体的颜色,并使其动画化:

css
.btn {
    font-size: 2rem;
    font-weight: 700;
    padding: 0.5em 1em;
    color: var(--clr-accent);
    background-color: var(--clr-rgba);
    border: 10px solid var(--clr-accent);
    border-radius: 5px;

    transition: transform 0.3s ease 0s, background-color 1s, color 1s;
}

.btn:hover {
    transform: translateY(-10px);
    background-color: var(--clr-accent);
    color: var(--clr-rgba);
}

不过这样一个一个进行动画化会很麻烦,所以就可以使用transition: all 0.3s;将其:hover的所有属性动画化。

animation

使用animationtransition的一个不同点在于,animation不需要鼠标移动或点击时就触发,而是开启页面即会自动开始;且animation可以更精细的使用关键帧对元素进行控制。

例如使用以下这段css,即可以让按钮从左移动到中间:

css
/* 为动画写好关键帧 */
@keyframes slideInLeft {
    /* 动画的开始 */
    from{
        transform: translateX(-300px);
    }
    /* 动画的结束 */
    to{
        transform: translateX(0px);
    }
}

.btn{
    /* 动画名称 */
    animation-name: slideInLeft;
    /* 动画持续时间 */
    animation-duration: 1.5s;
    /* 动画计时函数 */
    animation-timing-function: ease-in;
    /* 动画延迟 */
    animation-delay: 0s;
    /* 动画迭代计数,值1代表动画执行1次,值infinite为无限次执行 */
    animation-iteration-count: 1;
    /* 动画方向,值reverse代表反向运动,值normal代表正常 */
    animation-direction: normal;

    /* 动画填充模式 */
    /* none即为不作更改 */
    /* backwards会将第一个关键帧的样式应用到元素中(from) */
    /* forwards会将最后一个关键帧的样式应用到元素中(to) */
    /* both会使用开始的关键帧和最后一个关键帧(from and to) */
    animation-fill-mode: both;

    /* 这里backwards之所以会在最后向左移动了150px,原因即为在最后的时候不作更改 */
    transform: translateX(-150px);
}

以上代码注释中只在animation-direction: normal;的情况下分析了animation-fill-mode这个属性,关于更多可查看MDN文档

以上七个animation属性还可以进行简写,简写顺序为:

css
.btn{
    animation: name duration timing-function delay iteration-count direction fill-mode;
}

提高可重用性

当多个元素需要进行设置动画时,一个一个元素进行动画设置会显得代码冗余:

通过Slaying The Dragon的学习,可以这样进行书写css代码:

HTML
<body>
    <button class="btn bounce animate animate--slow">learn more</button>
    <button class="btn btn--green slideInLeft animate animate--fast">learn more</button>
    <button class="btn btn--red rotate animate animate--infinite animate--slow">learn more</button>
</body>
css
:root {
    --clr-accent-blue: #08a9c6;
    --clr-rgba-blue: #c9f2fc;

    --clr-accent-green: #3bee3b;
    --clr-rgba-green: #c5fdcc;

    --clr-accent-red: #c22828;
    --clr-rgba-red: #fcc9c9;
}

body {
    display: flex;
    height: 100vh;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    overflow: hidden;
}

.btn{
    /* 按钮样式 */
    font-size: 2rem;
    font-weight: 700;
    padding: 0.5em 1em;
    color:var(--clr-accent-blue);
    background-color: var(--clr-rgba-blue);
    border: 10px solid var(--clr-accent-blue);
    border-radius: 5px;
    margin: 10px;
}

.btn--green{
    color:var(--clr-accent-green);
    background-color: var(--clr-rgba-green);
    border: 10px solid var(--clr-accent-green);
}

.btn--red{
    color:var(--clr-accent-red);
    background-color: var(--clr-rgba-red);
    border: 10px solid var(--clr-accent-red);
}


.animate{
    /* 动画持续时间 */
    animation-duration: 1.5s;
    /* both会使用开始的关键帧和最后一个关键帧(from and to) */
    animation-fill-mode: both;
}

.animate.animate--infinite{
    /* 无限次数 */
    animation-iteration-count: infinite;
}

.animate.animate--delay-1s{
    animation-delay: 1s;
}

.animate.animate--fast{
    animation-duration: 0.6s;
}

.animate.animate--slow{
    animation-duration: 3s;
}

/* 为动画写好关键帧 */
@keyframes slideInLeft {
    /* 动画的开始 */
    from{
        transform: translateX(-300px);
    }
    /* 动画的结束 */
    to{
        transform: translateX(0px);
    }
}

.slideInLeft{
    animation-name: slideInLeft;
    animation-timing-function: ease-in;
}

/* 右移 */
@keyframes slideInRight {
    /* 动画的开始 */
    from{
        transform: translateX(300px);
    }
    /* 动画的结束 */
    to{
        transform: translateX(0px);
    }
}

.slideInRight{
    animation-name: slideInRight;
    animation-timing-function: ease-in;
}

/* 旋转 */
@keyframes rotate{
    from{
        transform: rotate(0);
    }
    to{
        transform: rotate(360deg);
    }
}

.rotate{
    animation-name: rotate;
    animation-timing-function: linear;

    /* 将其变更为绕左上角转动 */
    transform-origin: top left;
}

/* 弹跳 */
@keyframes bounce{
    0%,20%,50%,80%,100%{
        transform: translateY(0);
    }
    40%{
        transform: translateY(-30px);
    }
    60%{  
        transform: translateY(-15px);
    }
}

.bounce{
    animation-name: bounce;
}

Released under the MIT License.