基本概念
css中有两种形式实现动画效果:过渡动画transition
和自定义动画animation
。其中,animation动画可以循环多次执行,而过渡动画transition只执行一遍。
transition
若通过用户的交互直接改变css样式,呈现的形式是立即转变。若希望这个变化是有过渡效果的,便需要使用到过渡动画transition
。使用transition的例子如下:
1 | <template> |
transition简写方式
1 | transition: 使用过渡效果的属性名称 过渡时间 过渡方式 |
常见属性
transition-property:指定使用过渡效果的css属性
默认值为all,即所有能够被transition支持的属性都会有过渡效果。在实际使用时最好指定具体生效的属性,如只改变字体大小便设置为transition-property:font-size
。
目前transition不支持的过渡项有:z-index
、display
。
transition-duration:动画过渡时间
定义动画过渡时间,默认为0秒
transition-timing-function:动画过渡方式
定义动画的事件函数,控制动画速度,可以配置动画随时间变化的运动速率和轨迹。
可选值:
- linear:动画的速度从头到尾都是相同的
- ease(缓解):默认是动画从低速开始,然后加快,在结束前变慢
- ease-in:动画以低速开始
- ease-out:动画以低速结束
- ease-in-out:动画以低速开始和结束
- cubic-bezier(n,n,n,n):贝塞尔曲线(自定义数组),可到网站 cubic-bezier.com进行可视化配置
transition-delay: 动画延迟时间
设置动画延时时间,单位为秒。
若想要立即触发动画,只在恢复时延迟过渡,可以在动画触发时重新设置transition-delay:0s
。这样动画一旦触发就会应用对应的样式表,动画执行完毕后延时0秒恢复原样式。
当同时使用多个动画时,可依次定义每个动画的延迟执行时间,依次来区分每一个动画。
多属性累加
需要对每个属性的过渡效果分别设置时,可以使用逗号,
来分隔开。
1 | transition-property: width, heitht, color ; |
以上代码也可以使用简写方式来分隔,如:
1 | transition: width 1s ease ,heitht 1.5s linear 1s, color 2s ease-in-out ; |
animation
自定义动画通过@keyframes
来设置关键帧动画。可以对每一帧动画进行设置动画名称、时长、缓动函数、循环函数等信息。其语法如下:
1 | @keyframes animationName { |
其中,使用百分比来%
指定变化时的状态,0%
和100%
代表首尾帧,也可分别使用from
和to
来替代。
注意:若自定义动画没有自定义首尾帧,首尾帧将会应用元素原有的样式。
例如:
1 | @keyframes animationName { |
animation简写方式
1 | animation: 动画持续时间 延迟时间 执行关键帧名称 运动方式 循环次数 结束状态 动画执行顺序 |
最简方式:(其中执行时间和延迟时间顺序不可调整)
1 | animation: 动画执行时间 执行关键帧名称 |
常见属性
animation-name:指定使用的 @keyframes
名称
若元素想要使用对应名称的动画,则需要配置animation-name。
animation-duration: 动画持续时间
定义动画持续时间,默认为0秒
animation-iteration-count: 动画循环次数
定义动画迭代次数/执行次数,默认为1次
animation-timing-function: 动画运动方式
定义动画的缓动函数,控制动画速度,可以配置动画随时间变化的运动速率和轨迹。
可选值:
- linear:动画的速度从头到尾都是相同的
- ease(缓解):默认是动画从低速开始,然后加快,在结束前变慢
- ease-in:动画以低速开始
- ease-out:动画以低速结束
- ease-in-out:动画以低速开始和结束
- cubic-bezier(n,n,n,n):贝塞尔曲线(自定义数组),可到网站 cubic-bezier.com进行可视化配置
animation-delay: 动画延迟时间
设置动画延时时间,单位为秒。
当同时使用多个动画时,可依次定义每个动画的延迟执行时间,依次来区分每一个动画。
animation-direction: 动画执行顺序(播放方向)
设置动画执行的方向。
可选值:
- normal:默认值,动画按正常播放
- reverse:动画反向播放
- alternate(交替的):动画正反(正向->反向)交替执行
- alternate-reverse:动画反正(反向->正向)交替执行
- inherit:从父元素继承该属性
animation-fill-mode:动画结束状态
设置动画的填充模式
可选值:
- none:默认值,动画在动画执行前后,不会应用任何样式到目标元素。
- forwards:在动画结束后(由 animation-iteration-count 决定),目标元素将保持应用最后帧动画。
- backwards:在动画结束后(由 animation-iteration-count 决定),目标元素将保持应用起始帧动画。
animation-play-state:动画执行状态
设置动画的执行状态
可选值:
- running:允许
- paused:暂停。动画将停止执行
多动画累加
若元素应用多个动画时,可以通过给animation属性分别不同值来分别控制各个动画的属性。各个值之间使用逗号,
来分隔开。
1 | animation-name: bgcolor, bodera, rotat; |
应用多个动画时,所有动画是并发执行的,因此计算动画结束事件只需要知道执行时间最长的动画即可,执行时间 x 单次执行时间=动画总时间。因此上述代码的最大时间=max(2x2,2x2,3x1=4s。
animation用法示例
播放时长为2秒的浮动动画的Vue代码示例如下:
1 | <template> |
常见错误及解决方案
@keyframes
不能实现突变的状态变化
@keyframes
是将样式从一个状态慢慢转变为另一个状态,因此不能实现突变的状态,例如:
1 | div { |
上述代码中display:none;
是将div不占空间地隐藏,而display:block;
是显示div并占用空间。这里从display:none;
到display:block;
的状态是突变的,因此@keyframes
无法实现上述的状态变化
替代方法:
占据空间的隐藏:使用visibility来代替display。
1
2
3
4
5
6
7
8
9
10
11
12
13div {
animation: appear 2s;
}
@keyframes appear {
from {
opacity:1;
visibility:visible;
}
to {
opacity:0;
visibility:hidden;
}
}不占据空间地隐藏:使用绝对定位+visibility组合,其中绝对定位使元素脱离文档流,搭配z-index层级关系来使他出现或消失。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18div {
position:absolute;
top:0;
left:0;
animation: appear 2s;
}
@keyframes appear {
from {
opacity:1;
visibility:visible;
z-index:10;
}
to {
opacity:0;
visibility:hidden;
z-index:0;
}
}消失前占据空间但消失后不占空间:使用setTimeout和visibility组合。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40<template>
<div>
<button @click="hideElement">隐藏元素</button>
<div :class="{ 'fade-out': isVisible, 'hidden': !isVisible }">
这是一个会消失的元素
</div>
</div>
</template>
<script>
export default {
data() {
return {
isVisible: true,
};
},
methods: {
hideElement() {
this.isVisible = false;
// 使用 setTimeout 设置一定的延迟,确保元素在消失前渲染一段时间
setTimeout(() => {
this.isVisible = true;
}, 500); // 设置的时间可以根据需要调整
},
},
};
</script>
<style>
.fade-out {
visibility: visible;
opacity: 1;
transition: opacity 0.5s ease-in-out;
}
.hidden {
visibility: hidden;
opacity: 0;
}
</style>
@keyframes
会增添/覆盖属性
以下为覆盖属性的例子:
1 | /* |
在例子里,div的初始状态是 top:0px;
,在动画启动前,@keyframes
先用top:20px;
覆盖原属性,然后再开始播放动画