【前端基础】1 - 14 动画

§1-14 动画

1-14.1 动画与过渡

前面我们学习了属性 transition 可以实现元素在两个状态之间的变化过程,但无法做到多个状态间的变化过程,这是过渡属性的不足。

使用动画属性 animation,可以做到元素在多个状态间的变化过程,且该过程可控(循环播放、最终画面、暂停等)。

1-14.2 制作动画

关键帧:动画的基本组成是关键帧,关键帧由关键字 @keyframes 声明,语法:

/* 具有两个状态的动画关键帧 */
@keyframes animation-name {
    /* 始 */
    from {
        /* CSS code */
    }
    /* 终 */
    to {
        /* CSS code */
    }
}

/* 具有多个状态的动画关键帧 */
@keyframes animation-name {
    /* 该状态占动画时长百分比 */
    percentage1 {
        /* CSS code */
    }
    percentage2 {
        /* CSS code */
    }
    ...
    100% {
        /*CSS code*/
    }
}

注意

  • @keyframes 关键字后为动画名称,应当见名知意;
  • 可以使用 from, to 声明具有两种状态的动画,分别表示始态和末态;
  • 也可以使用百分比声明具有多种状态的动画;
  • 每个动画状态都由一对花括号包围,其中书写 CSS 代码;

调用动画:有了关键帧后,在需要应用动画的元素上施加属性 animation 应用动画即可。

该属性是一个复合属性,但具有两个必须的属性值:动画名称和动画时长。其他参数将在后文介绍。

<div class="animated"></div>
/* 一个简单的动画示例 */
.animated {
    margin: 20px auto;
    width: 100px;
    height: 100px;
    border-radius: 5px;
    background-color: pink;
    
    animation: widening 1.25s;
}

@keyframes widening {
    from {
        width: 100px;
    }
    to {
        width: 500px;
    }
}

在浏览器打开,会看到元素在出现的瞬间播放指定的动画(变宽),时长 1 秒,随后恢复原状。

1-14.3 animation 属性

animation 是一个复合属性,可以接受多个不同的参数,实际上是以下属性的简写:

属性 说明 默认值
animation-delay 动画延时,动画将在这个延时超时后播放 0s
animation-direction 动画方向 normal
animation-duration 动画持续时长 0s
animation-fill-mode 动画在执行前后如何将样式应用于目标 none
animation-iteration-count 动画迭代次数,动画重复播放的次数 1
animation-name 动画名称 none
animation-play-state 动画播放状态 running
animation-timing-function 动画速度,设置动画在每个周期的持续时间内如何进行 ease

注意

  • 一般而言,使用简写复合属性 animation 更佳;
  • 这些参数并没有顺序要求,可按需填写;
  • 仅填写唯一一个时间参数时,该参数为动画持续时长;
  • 填写两个时间常数时,前者为持续时长,后者为延时;
  • 若有多个动画需要应用至同一目标上,在不同的动画间使用逗号 , 分隔;

示例一:对元素应用 demo 动画

/* 动画 持续时间 */
/* 元素在加载完成时立刻播放动画,随后恢复原状 */
animation: demo 1.0s;

/* 动画 持续时间 延时 填充模式 */
/* 元素在加载完成 1.0s 后播放动画,随后保留动画结束时的状态 */
animation: demo 1.0s 1.0s forwards;

/* 动画 持续时间 延时 方向 迭代次数 */
/* 元素在加载完成 1.0s 后播放动画,动画将无休止地重复播放,先正向再反向 */
animation: demo 1.0s 1.0s alternative infinite;

/* 动画 持续时间 延时 动画速度 */
/* 元素在加载完成 1.0s 后播放动画,逐帧播放(适用于 Sprite 图动画) */
animation: demo 1.0s 1.0s step(5);

/* 动画 持续时间 延时 动画速度 */
/* 元素在加载完成 1.0s 后播放动画,线性播放(适用于字幕和走马灯) */
animation: demo 1.0s 1.0s linear;

/* 动画 持续时间 播放状态 */
/* 动画暂停播放(可在鼠标悬停时应用以暂停动画播放) */
animation: demo 1.0s 1.0s paused;

示例二:从右往左的走马灯

每张图片大小均为 480x270,共 7 张。走马灯宽度容纳三张图片。

<div class="trotting_horse_lamp">
    <ul>
        <li><img src="./../../resources/images/trotting_horse_lamp/1.jpg" alt="1"></li>
        <li><img src="./../../resources/images/trotting_horse_lamp/2.jpg" alt="1"></li>
        <li><img src="./../../resources/images/trotting_horse_lamp/3.jpg" alt="1"></li>
        <li><img src="./../../resources/images/trotting_horse_lamp/4.jpg" alt="1"></li>
        <li><img src="./../../resources/images/trotting_horse_lamp/5.jpg" alt="1"></li>
        <li><img src="./../../resources/images/trotting_horse_lamp/6.jpg" alt="1"></li>
        <li><img src="./../../resources/images/trotting_horse_lamp/7.jpg" alt="1"></li>
        <!-- 替补 -->
        <li><img src="./../../resources/images/trotting_horse_lamp/1.jpg" alt="1"></li>
        <li><img src="./../../resources/images/trotting_horse_lamp/2.jpg" alt="1"></li>
        <li><img src="./../../resources/images/trotting_horse_lamp/3.jpg" alt="1"></li>
    </ul>
</div>

这里考虑对 li 添加平移变换更易于控制。且为了实现 “循环滚动” (即首尾相接)的效果,将原 7 张图完全平移出父容器范围时,最后一帧应当补为动画的第一帧,因此,出现了三张替补图片,同第一帧的三张图片。

* {
    margin: 0;
    padding: 0;
}

img {
    vertical-align: middle;
}

li {
    list-style: none;
}

.trotting_horse_lamp {
    margin: 20px auto;
    width: 1440px;
    height: 270px;
    border: 5px solid black;
    overflow: hidden;
}

.trotting_horse_lamp ul {
    display: flex;
}

.trotting_horse_lamp li {
    animation: move 8s 1.0s linear infinite;
}

@keyframes move {
    0% {
        transform: translate(0%);
    }
    100% {
        transform: translate(-700%);
    }
}

.trotting_horse_lamp:hover li {
    animation-play-state: paused;
}

示例三:使用 Sprite 图制作逐帧动画。

所使用的 Sprite 图必需是由一连串帧图片所形成的长图。在正式制作逐帧动画前,先要明确这张图中所包含的帧数,以及单帧图像的宽高

然后,在 HTML 文档中新建一个宽高同单帧图像宽高的容器。这里以一张 1680x140,单帧图像 140x140 的 Sprite 图为例:

<div class="sprite_animation"></div>
.sprite_animation {
    /* 将宽高设为同单帧图像的宽高 */
    width: 140px;
    height: 140px;
    border: 2px solid black;
    /* 背景图设为所用 Sprite 图 */
    background-image: url(./../../../resources/images/sprite_animation.png);
}

然后,设置动画:

@keyframes run {
    /* 始态同元素状态,可省略 */
    to {
        /* 末态将图片平移到最边缘 */
        background-position: -1680px 0;
    }
}

将动画应用到元素上:

.sprite_animation {
    /* 前文所设置的代码 */
    ...
    /* 动画速度使用 steps(),其中参数填入 Sprite 图中图像总帧数 */
    animation: run 0.8s steps(12) infinite;
}
posted @ 2024-03-09 21:03  Zebt  阅读(2)  评论(0编辑  收藏  举报