帧动画通过定义一段动画中的关键点、关键状态来创建动画。
transition虽然也有对帧的控制,但是控制粒度往往比较大,其主要是对一个变化过程,比如:宽度/背景变化过程中,设置变化时间/速度以及在哪开始变化。虽然里面也有类似于帧的transition-timing-function: steps(5,start)
控制每一帧,但是每一帧都是对同一变化进行控制的。而对于想要对元素变化时设置不同效果,显然是不适用的。
这个时候可以使用animation
来解决。
-
transition
过渡是两个状态间的变化。 -
animation
帧动画是不同时间点设置不同状态的变化
1. 关键帧
因为可以对每个帧动画设置,因此使用@keyframes
对每一帧设置动画。
属性值
值 | 说明 |
---|---|
from | 表示起始点 |
to | 表示终点 |
百分比 | 表示动画运行到百分比处的时间时的动作。 |
基本使用:
@keyframes my {
from {
transform: translateX(20px);
}
to {
transform: translateX(-40px);
}
}
此处定义了两个帧,分别是from,和to。通过自定义名称my
来便于之后进行引用。但是自定义名称不能跟帧动画中的关键字重叠。
要使用通过帧定义的动画,需要在指定元素处进行声明。
animation-name
用于声明帧动画。
div {
animaition-name: my;// my 为自定义名称,与帧动画对应
}
声明了帧动画之后,当前元素还是不会产生动画。
原因:帧动画是对动画时间进行划分,在每一份时间中产生动画。
通过animation-duration: s/ms
声明动画时间。
查看如下代码:
main:hover div {
// 定义帧动画为my
animation-name: my;
// 定义帧动画时间为5s
animation-duration: 5s;
}
@keyframes my {
from {
transform: translateX(20px);
}
to {
transform: translateX(-40px);
}
}
以上代码表示,当鼠标悬浮于main上的时候,div会有5s的动画,而这个动画定义为my,动画my中对5s进行了两次划分,为动画开始时元素需要在X轴正方向移动20px,另一次为当动画快结束的时候元素需要在上一次动画完成之后的位置在X轴负方向移动40px,动画结束之后回到元素最初的状态。
所以效果为:
假如使用百分比定义帧动画:
main:hover div {
animation-name: my;
animation-duration: 5s;
}
@keyframes my {
0% {
background-color: #fff;
}
50% {
width: 300px;
height: 300px;
background: #000;
}
100% {
transform: scale(0);
}
}
以上代码表示:当鼠标悬浮于main上的时候,div盒子会有5s的动画。该动画为my,动画my中将5s时间划分为3份。
- 第一份为0s开始的时候,背景颜色为白色,但是由于该盒子最初的颜色为蓝色,所以可以看到蓝色在动画开始时快速变为白色。
- 第二份为0s到2.5s,也可以准确的说为第一帧动画结束之后到2.5s时作为第二帧动画的变化,也即高度/宽度/背景颜色的变化。
- 第三份为2.5s到5s,也即第二帧动画结束之后到5s时作为第二帧动画的变化,也即在上一个动画变化之后的基础上,对元素进行缩放效果。
最后动画结束,元素回到最初的状态。(如果不设置动画其他属性的情况下,默认动画结束回到最初的状态)
值得注意的是:如果0%以及100%的时候的状态希望是元素最初的状态时,可以不进行设置,因为如果不设置,默认0%和100%为元素最初的状态。
除了分别设置百分比的效果外,类似于声明CSS选择器一样,可以同时对处于不同百分比的状态下进行设置效果,
比如:
@keyframe my {
0%,
100% {
border-radius: 50%;
}
25%,
75% {
background-color: #fff;
}
}
1.1 定义多个帧动画
一个元素不止可以定义一个帧动画,可以定义多个。
animation-name: 帧动画1,帧动画2...;
1.1.1 相同动画时间
如果只设置了一个动画时间,那么默认所有的帧动画的动画时间都是一致的。
比如:
main:hover div {
// 对一个元素使用多个帧动画
animation-name: my,other;
animation-duration: 5s;
}
@keyframes my {
0% {
width: 50px;
height: 50px;
}
50% {
width: 200px;
height: 200px;
}
100% {
width: 300px;
height: 300px;
}
}
@keyframes other {
0% {
background-color: #fff;
}
50% {
background: #000;
}
100% {
background-color: #e1b12c;
}
}
以上代码表示,当鼠标悬浮于main上的时候,div盒子在5s时间内会有两个动画,且这两个动画都是将5s划分为三份,每一份做着相应的动作。
以上的例子中不同动画的帧中设置的属性都是不相同的,那如果有相同的属性值,会怎么样呢?结果是:后面动画属性优先使用。
也即在相同的时间内,相同属性的动画,后面的动画显示会覆盖前一个动画属性的变化,导致前一个属性动画失效。
比如:
main:hover div {
animation-name: my,other;
animation-duration: 5s;
}
@keyframes my {
0% {
width: 50px;
height: 50px;
}
50% {
width: 200px;
height: 200px;
}
100% {
width: 300px;
height: 300px;
}
}
@keyframes other {
0% {
background-color: #fff;
width: 200px;
height: 200px;
}
50% {
background: #000;
}
100% {
background-color: #e1b12c;
}
}
以上定义了两个帧动画,且同时应用于div上,other动画放于my动画之后,可以看到other动画中有宽度/高度的变化,因此在同一时间交叉处(other的0%覆盖了my的0%)other动画会先对宽度/高度进行变化,所以my的0%动画变化失效,看到元素直接变为200px
1.1.2 不同动画时间
如果设置不同的时间,那么每个时间循环应用到帧动画上。
main:hover div {
animation-name: my,other;
animation-duration: 4s,100ms;
}
此时my动画划分时间为4s,other动画划分时间为100ms。
main:hover div {
animation-name: my,other,two;
animation-duration: 4s,100ms;
}
此时my动画划分时间为4s,other划分时间为100ms,two划分时间为4s。
2. 重复动画
之前的属性所定义的动画都只能运行一次,但是可以使用animation-iteration-count
定义动画运行多次。
属性值:
- 整数n,代表运行n次
- infinte,代表运行无数次
可以设置多个属性值,用法与animation-duration
一致
main:hover div {
animation-name: my;
animation-duration: 1s;
// 定义2次动画
animation-iteration-count: 2;
}
@keyframes my {
0% {
width: 50px;
height: 50px;
}
50% {
width: 200px;
height: 200px;
}
100% {
width: 300px;
height: 300px;
}
}
3. 动画方向
默认情况下,动画的方向是从0%帧到100%方向变化,然后100%帧动画执行完成之后,快速回到0%帧处。
但是可以使用animation-direction
控制动画方向,让其不止从0%到100%,也可以让其从100%到0%,或者改变回到初始状态的速度。
属性值:
属性值 | 说明 |
---|---|
normal | 从0%到100%运行动画,并快速回到0% |
reverse | 从100%到0%运行动画,并快速回到100% |
alternate | 先从0%到100%,然后从100%到0%,中间过程平滑进行 |
alternate-reverse | 先从100%到0%,然后从0%到100%,中间过程平滑进行 |
4. 动画延迟
使用animation-delay
控制多久之后才开始动画
属性单位:s/ms
5. 动画速率
类似于过渡速度transition-timing-function
控制一样,动画也可以控制整个动画的速率。如果需要对动画的某些帧进行设置,此时就需要使用transition-timing-function
使用animation-timing-function
进行控制。
可以参考:CSS3过渡延迟总结
5.1 平滑动画
属性值 | 说明 |
---|---|
linear | 规定以相同速度开始至结束的过渡效果(等于 cubic-bezier(0,0,1,1))。 |
ease | 开始慢,然后快,慢下来,结束时非常慢(cubic-bezier(0.25,0.1,0.25,1)) |
ease-in | 开始慢,结束快(等于 cubic-bezier(0.42,0,1,1)) |
ease-out | 开始快,结束慢(等于 cubic-bezier(0,0,0.58,1)) |
ease-in-out | 中间快,两边慢(等于 cubic-bezier(0.42,0,0.58,1)) |
cubic-bezier(n,n,n,n) | 在 cubic-bezier 函数中定义自己的值 |
cubic-bezier使用与transition-timing-function
使用一致
5.2 步进动画
使用steps(n,start/end) step-start step-end
使用与transition-timming-function
中的步进一致
6. 播放状态
默认情况下,动画是在running
状态的。
可以使用animation-play-state
控制动画状态
属性值 | 说明 |
---|---|
running | 动画正常运行 |
paused | 动画不执行,暂停在某一帧上 |
当鼠标移入时,暂停动画,可以看到当暂停的时候,动画停留在某一帧上,而不是回到初始状态。
7. 填充模式
animation-fill-mode
用于定义动画播放结束后的处理模式,是回到原来的状态还是停止在动画结束状态。
默认情况下,如果设置了延迟,那么会先延迟指定时间,再从定义的第一帧开始进行变化,到最后一帧结束之后,元素回到最初的状态。
属性值 | 说明 |
---|---|
none(默认值) | 需要等延迟结束,起始帧属性才应用,且最后回到元素最初的状态 |
backwards | 延迟时间内效果为第一帧动画状态,接着等延迟结束之后,再从第一帧开始变化。 |
forwards | 所有帧动画结束后停留动画的最后一帧状态 |
both | 包含backwards与forwards规则,即动画效果在起始帧,不等延迟结束,并且在结束后停止在最后一帧 |
案例:
- normal
- backwards
- forwards
- both