CSS animation 属性
定义和用法 animation 属性是一个简写属性,用于设置六个动画属性:
- animation-name
- animation-duration
- animation-timing-function
- animation-delay
- animation-iteration-count
- animation-direction
- 注释:请始终规定
animation-duration
属性,否则时长为 0,就不会播放动画了 !!!!!。
- CSS 语法
animation: name duration timing-function delay iteration-count direction;
值 | 描述 |
---|---|
animation-name | 规定需要绑定到选择器的 keyframe 名称。 |
animation-duration | 规定完成动画所花费的时间,以秒或毫秒计。 |
animation-timing-function | 规定动画的速度曲线。 |
animation-delay | 规定在动画开始之前的延迟。 |
animation-iteration-count | 规定动画应该播放的次数。 |
animation-direction | 规定是否应该轮流反向播放动画。 |
animation-fill-mode | 规定动画在执行时间之外应用的值。 |
animation-play-state | 规定动画是正在运行还是暂停。 |
基本了解
css中实现动画有两种方式:transition
过渡动画、 animation
自定义动画。
animation
动画的使用,若要了解transition
过渡动画请前往transition过渡动画。
简单了解下animation的一些语法和使用过程,后面会详细解说:
通过
@keyframes
自定义关键帧动画并为动画命名,可以在其中对每一帧进行设置。使用自定义动画的元素,需要通过
animation
相关属性进行配置
- animation-name
- animation-duration
- animation-timing-function
- animation-delay
- animation-iteration-count
- animation-direction
- animation-fill-mode
- animation-play-state
我们还可在JavaScript中,通过驼峰式命名来访问/设置animation
相关属性。
@keyframes
keyframes(关键帧),在css样式表中可以通过@keyframes
来设置关键帧动画,并指定动画名称供使用者锁定。
其语法如下:
我们可以通过百分比来设置具体帧数的样式。
@keyframes animateName{
0% { width:50px; height:50px; }
50% { width:100px; height:100px; }
100% { width:50px; height:50px; }
}
0%
和100%
代表首尾帧
,也可分别使用from
、to
替代。下面代码与上述代码效果相同
@keyframes animateName{
from { width:50px; height:50px; }
50% { width:100px; height:100px; }
to { width:50px; height:50px; }
}
需要注意的是: 若自定义动画未定义首尾帧,则首尾帧将会应用使用者的原有样式
现在动画定义完毕,使用者需要配置animation
相关属性对动画进行配置。
animation-name
若某个元素想要使用对应名称的动画,需要配置animation-name: animateName
属性进行锁定。
<style>
.box {
width: 50px;
height: 50px;
background-color: pink;
animation-name: test;
animation-duration: 1s;
animation-iteration-count: infinite;
}
@keyframes test {
50% {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: skyblue;
}
}
</style>
<body>
<div class="box"></div>
</body>
这里为了让动画更加明显,使用了animation-duration
与animation-iteration-count
,这里简单介绍一下:
animation-duration
用于定义动画持续时间,默认0s
animation-iteration-count
用于定义动画迭代次数,也就是执行次数,默认为1
。
animation-duration
animation-duration
顾名思义,用于设置动画持续时间.
需要注意的是:默认值为0s
,也就是说,若不配置animation-duration
则默认请况下是没有动画效果的,即便使用animation-name
锁定了动画名称,由于动画持续时间为0s
,所以没有效果。
animation-timing-function:
animation-timing-function
用于定义时间函数,通过这个选项,可配置动画随时间的运动速率和轨迹。
值 | 描述 |
---|---|
linear | 动画从头到尾的速度是相同的。 |
ease(缓解) | 默认值 :动画以低速开始,然后加快,在结束前变慢。 |
ease-in | 动画以低速开始。 |
ease-out | 动画以低速结束。 |
ease-in-out | 动画以低速开始和结束。 |
cubic-bezier(n,n,n,n) | 贝塞尔曲线(自定义数值),可到相关网站可视化设置。 |
<style>
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
body {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
background-color: #34495e;
}
ul {
display: flex;
flex-direction: row;
justify-content: center;
list-style: none;
display: flex;
}
ul > li {
width: 40%;
margin: 0px 40px;
position: relative;
}
ul > li > .fa {
font-size: 4em;
color: white;
opacity: 0.8;
animation: test 2s infinite;
}
@keyframes test {
to {
transform: translateY(86vh);
}
}
ul > li:nth-of-type(1) > .fa {
animation-timing-function: linear;
}
ul > li:nth-of-type(2) > .fa {
animation-timing-function: ease;
}
ul > li:nth-of-type(3) > .fa {
animation-timing-function: ease-in;
}
ul > li:nth-of-type(4) > .fa {
animation-timing-function: ease-out;
}
ul > li:nth-of-type(5) > .fa {
animation-timing-function: ease-in-out;
}
ul > li:nth-of-type(6) > .fa {
animation-timing-function: cubic-bezier(0.29, 1.69, 0.39, -0.05);
}
li > span {
position: absolute;
color: #f1c40f;
}
strong {
color: #e67e22;
margin: 10px;
}
</style>
<body>
<strong>animatin-timing-function:</strong>
<ul>
<li>
<span>linear<br />线性</span>
<div class="fa">👇</div>
</li>
<li>
<span>ease<br />默认。动画以低速开始,然后加快,在结束前变慢。</span>
<div class="fa">👇</div>
</li>
<li>
<span>ease-in<br />以低速开始</span>
<div class="fa">👇</div>
</li>
<li>
<span>ease-out<br />以低速结束</span>
<div class="fa">👇</div>
</li>
<li>
<span>ease-in-out<br />以低速开始和结束</span>
<div class="fa">👇</div>
</li>
<li>
<span>cubic-bezier()<br />贝塞尔曲线(自定义数值)</span>
<div class="fa">👇</div>
</li>
</ul>
</body>
animation-delay
animation-delay`用于设置动画延迟时间,单位为`s
下例动画将于2s
后执行
.box {
width: 50px;
height: 50px;
background-color: pink;
animation-name: test;
animation-duration: 1s;
animation-delay: 2s;
}
@keyframes test {
50% {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: skyblue;
}
}
当同时使用多个动画时,这个属性使用频率非常高,可依次定义每个动画的延迟执行时间,区分开每个动画。
当然其实也可分别设置每个动画的其它animation族属性,后面会详细介绍多动画累加。
animation-iteration-count:
animation-iteration-count
用于设置动画执行的次数,默认值为1
只执行一次。
其值可分为两种:
- 具体number数值
infinite
:执行无限次
animation-direction
animation-direction
用于设置动画执行方向,具体来说可设置为以下值:
值 | 描述 |
---|---|
normal | 默认值。动画按正常播放。 |
reverse | 动画反向播放。 |
alternate(交替的) | 动画正向交替执行(正向->反向)Loop。 |
alternate-reverse | 动画反向交替执行(反向->正向)Loop。 |
inherit | 从父元素继承该属性。 |
效果展示:
<style>
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
body {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
background-color: #34495e;
justify-content: center;
align-items: center;
}
ul {
display: flex;
flex-direction: row;
list-style: none;
width: 300px;
height: 300px;
justify-content: center;
align-items: center;
}
ul > li {
margin: 0px 40px;
/* border: 2px solid #ddd; */
display: flex;
flex-direction: column;
color: #e74c3c;
justify-content: center;
align-items: center;
}
ul > li > .fa {
animation: test 1.3s infinite;
font-size: 7em;
}
ul li:nth-of-type(1) > .fa {
animation-direction: normal;
}
ul li:nth-of-type(2) > .fa {
animation-direction: reverse;
}
ul li:nth-of-type(3) > .fa {
animation-direction: normal;
}
ul li:nth-of-type(4) > .fa {
animation-direction: reverse;
}
@keyframes test {
100% {
transform: scale(1.7);
}
}
h1 {
color: white;
opacity: 0.8;
}
li > span {
font-size: 24px;
margin: auto;
margin-top: 30px;
}
body ul:nth-of-type(2) li:nth-of-type(1) > .fa {
animation-direction: alternate;
}
body ul:nth-of-type(2) li:nth-of-type(2) > .fa {
animation-direction: alternate-reverse;
}
strong {
font-size: 20px;
color: white;
opacity: 0.76;
}
</style>
<body>
<h1>animation-direction:</h1>
<ul>
<li>
<div class="fa">❤</div>
<span>normal</span>
<p>默认值/正向</p>
</li>
<li>
<div class="fa">❤</div>
<span>reverse</span>
<p>反向进行动画</p>
</li>
</ul>
<strong
>可以利用默认值normal和reverse,交叉动画的效果,<br />也可以正反向反复交替如下。</strong
>
<ul>
<li>
<div class="fa">❤</div>
<span>alternate</span>
<p>反复交替(正向)</p>
</li>
<li>
<div class="fa">❤</div>
<span>alternate-reverse</span>
<p>反复交替(反向)</p>
</li>
</ul>
</body>
animation-fill-mode
animation-fill-mode
用于设置动画的填充模式,主要应用的属性值为:
值 | 描述 |
---|---|
none | 默认值。动画在动画执行前后,不会应用任何样式到目标元素。 |
forwards | 在动画结束后(由 animation-iteration-count 决定),目标元素将保持应用最后帧 动画。 |
backwards | 在动画结束后(由 animation-iteration-count 决定),目标元素将保持应用起始帧 动画。 |
案例测试:
下例代码,在动画执行结束后,将会一直应用最后帧的样式。
.box {
width: 50px;
height: 50px;
background-color: pink;
animation-name: test;
animation-delay: 2s;
animation-duration: 1s;
animation-fill-mode: forwards;
/* animation-iteration-count: infinite; */
}
@keyframes test {
100% {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: skyblue;
}
}
注意:上述代码若添加animation-iteration-count: infinite
,由于动画次数无限执行,不会结束,也就不会应用最后帧样式
animation-play-state
可设置动画的执行状态,通常通过JavaScript动态控制。
- 默认值为:
running
- 设为
paused
(暂停),动画将停止执行。
下面动画将不会执行
.box {
width: 50px;
height: 50px;
background-color: pink;
animation-name: test;
animation-delay: 2s;
animation-duration: 1s;
animation-play-state: paused; //值为paused将不会执行
}
@keyframes test {
50% {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: skyblue;
}
}
通过JavaScript动态控制:
<style>
.box {
width: 50px;
height: 50px;
background-color: pink;
animation-name: test;
animation-duration: 1s;
animation-iteration-count: infinite;
}
@keyframes test {
50% {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: skyblue;
}
}
</style>
<body>
<div class="box"></div>
<button onclick="operation('running')">开始</button>
<button onclick="operation('paused')">停止</button>
<script>
function operation(mode) {
document.querySelector("div").style.animationPlayState = mode;
}
</script>
</body>
多动画累加
若元素应用多个动画,我们可以分别控制各个动画的一些属性,来达到区分各个动画的效果。
下面示例,给animation
族属性分别设置多个值,来对不同的动画做不同的配置。
animation
族属性设置多个值时,各个值之间使用,
隔开。
案例:
- 首先使用
animation-name
来锁定使用的各个动画 - 之后使用其它的
animation
族属性,分别约束对应动画,且设置顺序与animation-name
使用动画的顺序保持一致。
<style>
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
body {
background-color: #353b48;
}
main {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
background-color: #487eb0;
animation-name: bgcolor, bodera, rotat;
animation-duration: 2s, 2s, 3s;
animation-iteration-count: 2, 2, 1;
animation-direction: reverse, normal, normal;
animation-fill-mode: forwards, forwards, forwards;
}
main::after {
content: "阿顺特烦恼";
color: white;
animation: opcity 2s;
opacity: 0;
font-size: 1.5em;
animation-fill-mode: forwards;
animation-delay: 4s;
}
@keyframes opcity {
25% {
opacity: 0.2;
}
50% {
opacity: 0.6;
}
100% {
opacity: 0.8;
}
}
@keyframes bgcolor {
25% {
background-color: #fbc531;
}
50% {
background-color: #8c7ae6;
}
75% {
background-color: #f5f6fa;
}
100% {
background-color: #e84118;
}
}
@keyframes bodera {
25% {
border-radius: 10%;
}
50% {
border-radius: 25%;
}
75% {
border-radius: 38%;
}
100% {
border-radius: 50%;
}
}
@keyframes rotat {
25% {
transform: rotate(30deg);
}
50% {
transform: rotate(60deg);
}
75% {
transform: rotate(120deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<body>
<main></main>
</body>
关键代码解析:
main {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
background-color: #487eb0;
animation-name: bgcolor, bodera, rotat;
animation-duration: 2s, 2s, 3s;
animation-iteration-count: 2, 2, 1;
animation-direction: reverse, normal, normal;
animation-fill-mode: forwards, forwards, forwards;
}
main::after {
content: "阿顺特烦恼";
color: white;
animation: opcity 2s;
opacity: 0;
font-size: 1.5em;
animation-fill-mode: forwards;
animation-delay: 4s;
}
这里为了让文字在其他动画都执行完毕后再显示,为文字动画设置了
animation-delay
延迟执行,但我们要确定之前动画结束的时间,怎么计算呢?我们知道,当应用多个动画时,它们也都是并发执行的,所以我们只要知道执行时间最长的那个动画即可。
animation-duration: 2s, 2s, 3s;
animation-iteration-count: 2, 2, 1;
- 执行次数×单次执行时间=动画总时间。因此最大时间=max(2×2 ,2×2, 3×1)=4s
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./vue.min.js"></script>
</head>
<style>
.app {
width: 600px;
height: 600px;
border: 1px solid black;
background-color: #88af7c;
animation-name: lusifer;
animation-duration: 2s;
display: flex;
flex-direction: column;
}
@keyframes lusifer {
0% {
width: 50px;
height: 50px;
}
50% {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: skyblue;
}
100% {
width: 600px;
height: 600px;
}
}
.cad {
flex: 1;
border: 1px solid black;
}
/* 显示或关闭动画* /
.open {
animation: slideContentUp 0.3s linear both;
}
.close {
animation: slideContentDown 0.3s linear both;
}
/* 动态设置高度 */
/* @keyframes slideContentUp {
from {
height: 0;
}
to {
height: 80vh;
}
}
@keyframes slideContentDown {
from {
height: 80vh;
}
to {
height: 0;
}
}
*/
/* 显示或关闭动画*/
.open {
animation: left 2s ease-in both;
}
.close {
animation: right 2s ease-in both;
}
@keyframes left {
from {
width: 50px;
/*最小的宽度,隐藏就写0,我这边图标静止需要一个宽度*/
}
to {
width: 250px;
/*最大展开的宽度*/
}
}
@keyframes right {
from {
width: 250px;
}
to {
display: none;
;
width: 0px;
}
}
.content {
background-color: #cabcbc;
width: 100px;
height: 100%;
border-radius: 15px;
}
</style>
<body>
<div id="vapp" class="app">
<div class="cad">{{ msg}}
<button @click="catVis()">显示</button>
</div>
<div class="cad">
<div class="content" :class="{
'open': visible,
'close': !visible
}">
你的内容
</div>
</div>
<div class="cad">cc</div>
</div>
<script>
let vm = new Vue({
el: '#vapp',
data() {
return {
visible: false,
msg: 'hello world'
}
},
methods: {
catVis() {
vm.visible = !vm.visible
console.log(vm.visible);
}
}
, mounted() {
console.log('init app');
}
})
</script>
</body>
</html>