【前端基础】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;
}