CSS帧动画
2021-01-17 08:12
标签:动作 次数 step 分数 org tps ansi evel 运动 通过定义一段动画中的关键点、关键状态来创建动画。 过渡动画是两个状态间的变化,帧动画可以处理动画过程中不同时间的细节变化, 对过渡动画理解后再学习习帧动画会非常容易,也可以把帧动画理解为多个帧之间的过渡动画。 一句话,帧动画是CSS中的大杀器,你应该充分的了解并掌握它。 使用 from 表示起始点 to表示终点 可以使用百分数如 20% 代表动画运行到20%处 下面使用 注意:动画命名不要使用CSS关键字如
可以看到上面的动画是从 不要着急,下面会介绍各种方法让你的帧动画随心所欲。 帧动画需要定义在不同时间执行的动作,开始与结束可以使用 必须添加百分号,25%是正确写法 时间点没有顺序要求,即100%写在25%前也可以 未设置 你可以这么理解,目前所学的一组帧动画它的运行应该是这样的 初始状态 ---> 0% 或者 from ---> 100% 或者 to ---> 初始状态 所以现在看上面的动画,就知道为什么看起来比较生硬了。 下面定义不同时间点来让物体元素移动一圈,下例中可以不设置
时间点可以动画样式一样时可以一起声明,下面将25%/75%背景一起声明。
使用 使用多个动画时用逗号分隔多个 动画有相同属性时,后面动画的属性优先使用
使用 可以使用m秒,ms毫秒时间单位 可为不同动画单独设置执行时间 如果动画数量大于时间数量,将重新从时间列表中计算 。 如一个动画有Move,Radius,Background 而时间是1s,2s,那么Move的时间是1s,Radius的时间是2s,Background的时间从头开始数,又是1s. 如下图的过渡时间,圆角是六秒完成,背景色是四秒完成,移动是两秒完成,但是他们的开始时间都是一样的。
不是所有css属性都有过渡效果,查看支持动画的CSS属性 ,一般来讲有中间值的属性都可以设置动画如宽度、透明度等。 如何理解中间值? 比如,一个元素的宽度从100px变为200px,那么它们之间就有中间值。 而一个元素的边框样式从实心线变为虚心线,他们就没有中间值。 看下面这张图,从实心线变为虚心线是瞬间变化,而背景颜色的改变却是跟着动画时间来进行渐变的。
可以看下下面这个例子,左边的块 而右边块的
CSS帧动画
基础知识
@Keyframes
相比transition
对动画过程和细节有更强的控制。关键帧
@keyframes
规则配置动画中的各个帧
基本使用
@keyframes
定义了动画叫 radius
并配置了两个帧动作from/to
,然后在main:hover div
中使用animation-name
引用了动画并使用animation-duration
声明执行三秒。
none
30%
的圆角过渡到了50%
的圆角,但是整个动画的结束是瞬间结束,整个动画并不完美。DOCTYPE html>
html lang="en">
head>
meta charset="UTF-8">
meta name="viewport" content="width=device-width, initial-scale=1.0">
title>Documenttitle>
style>
*{
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
main{
height: 200px;
width: 200px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #ddd;
}
div{
height: 100px;
width: 100px;
background: #5352ed;
}
?
main:hover div{
/* 一组帧的名字 */
animation-name: radius;
/* 动画时长 */
animation-duration: 3s;
}
?
@keyframes radius{
from{
border-radius: 30%;
}
to{
border-radius: 50%;
}
}
style>
head>
body>
main>
div>div>
main>
body>
html>
时间点
form/to
或 0%/100%
声明。
0%
与100%
时将使用元素原始状态
物体移动
from/to
系统将定义为元素初始状态。DOCTYPE html>
html lang="en">
head>
meta charset="UTF-8">
meta name="viewport" content="width=device-width, initial-scale=1.0">
title>Documenttitle>
style>
*{
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
main{
height: 400px;
width: 400px;
display: flex;
justify-content: flex-start;
align-items: flex-start;
border: 1px solid #ddd;
}
div{
height: 100px;
width: 100px;
background: #5352ed;
}
?
main:hover div{
/* 一组帧的名字 */
animation-name: move;
/* 动画时长 */
animation-duration: 3s;
}
?
@keyframes move{
/* 初始状态 ---> 帧 ---> 初始状态 */
25%{
transform: translate(300px,0);
}
50%{
transform: translate(300px,300px);
}
75%{
transform: translate(0,300px);
}
?
}
style>
head>
body>
main>
div>div>
main>
body>
html>
同时声明
DOCTYPE html>
html lang="en">
head>
meta charset="UTF-8">
meta name="viewport" content="width=device-width, initial-scale=1.0">
title>Documenttitle>
style>
*{
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
main{
height: 400px;
width: 400px;
display: flex;
justify-content: flex-start;
align-items: flex-start;
border: 1px solid #ddd;
}
div{
height: 100px;
width: 100px;
background: #5352ed;
}
?
main:hover div{
/* 一组帧的名字 */
animation-name: move;
/* 动画时长 */
animation-duration: 3s;
}
?
@keyframes move{
/* 初始状态 ---> 帧 ---> 初始状态 */
25%{
transform: translate(300px,0);
}
50%{
transform: translate(300px,300px);
}
75%{
transform: translate(0,300px);
}
?
25%,75%{
background: #ff4757;
}
?
50%,100%{
background: #5352ed;
}
?
}
style>
head>
body>
main>
div>div>
main>
body>
html>
使用动画
animation-name
规则可以在元素身上同时使用多个动画。
基本使用
DOCTYPE html>
html lang="en">
head>
meta charset="UTF-8">
meta name="viewport" content="width=device-width, initial-scale=1.0">
title>Documenttitle>
style>
*{
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
main{
height: 400px;
width: 400px;
display: flex;
justify-content: flex-start;
align-items: flex-start;
border: 1px solid #ddd;
}
div{
height: 100px;
width: 100px;
background: #5352ed;
}
?
main:hover div{
/* 一组帧的名字 可以使用多组帧*/
animation-name: move,radius;
/* 动画时长 */
animation-duration: 3s;
}
?
@keyframes move{
/* 初始状态 ---> 帧 ---> 初始状态 */
25%{
transform: translate(300px,0);
}
50%{
transform: translate(300px,300px);
}
75%{
transform: translate(0,300px);
}
/* 相同设置,前者不生效 */
?
25%,75%{
background: #ff4757;
}
?
50%,100%{
background: #5352ed;
}
?
}
?
@keyframes radius{
?
25%{
border-radius: 50%;
}
50%{
border-radius: 30%;
}
75%{
border-radius: 50%;
}
?
/* 相同设置后者覆盖前者,所以移动时的颜色会变为下面两种 */
?
25%,75%{
background: #ffa502;
}
?
50%,100%{
background: #2ed573;
}
?
}
style>
head>
body>
main>
div>div>
main>
body>
html>
动画时间
animation-duration
可以声明动画播放的时间,即把所有帧执行一遍所需要的时间。
效果体验
DOCTYPE html>
html lang="en">
head>
meta charset="UTF-8">
meta name="viewport" content="width=device-width, initial-scale=1.0">
title>Documenttitle>
style>
*{
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
main{
height: 400px;
width: 400px;
display: flex;
justify-content: center;
align-items: flex-start;
border: 1px solid #ddd;
}
div{
height: 100px;
width: 100px;
background: #5352ed;
}
?
main:hover div{
/* 一组帧的名字 可以使用多组帧*/
animation-name: radius,background,move;
/* 动画时长 圆角是六秒完成,背景色是四秒完成,移动是两秒完成,但是他们的开始时间都是一样的 */
animation-duration: 6s,4s,2s;
/* 将动画停留在最后一帧 */
animation-fill-mode: forwards;
}
?
@keyframes radius{
to{
border-radius: 50%;
}
}
@keyframes background{
to{
}
}
@keyframes move{
to{
transform: translate(0,150px);
}
}
?
style>
head>
body>
main>
div>div>
main>
body>
html>
动画属性
效果体验
DOCTYPE html>
html lang="en">
head>
meta charset="UTF-8">
meta name="viewport" content="width=device-width, initial-scale=1.0">
title>Documenttitle>
style>
*{
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
main{
height: 400px;
width: 400px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #ddd;
}
div{
height: 200px;
width: 200px;
background: #5352ed;
/* 添加实心线 */
border: 15px solid red;
}
?
main:hover div{
/* 一组帧的名字 可以使用多组帧*/
animation-name: border-style,background;
/* 动画时长 */
animation-duration: 2s;
/* 将动画停留在最后一帧 */
animation-fill-mode: forwards;
?
}
?
@keyframes border-style{
to{
border:15px dotted red ;
}
}
@keyframes background{
to{
}
}
?
style>
head>
body>
main>
div>div>
main>
body>
html>
中间值
from
与to
设置的尺寸单位没有中间值,所以是瞬间变大。from
与to
设置的尺寸单位是具有中间值的,所以是跟随动画时间进行渐变。DOCTYPE html>
html lang="en">
?
head>
meta charset="UTF-8">
meta name="viewport" content="width=device-width, initial-scale=1.0">
title>Documenttitle>
style>
* {
margin: 0;
padding: 0;
list-style: none;
box-sizing: border-box;
}
?
body {
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
}
?
main {
height: 400px;
width: 400px;
display: flex;
justify-content: space-evenly;
align-items: center;
border: 1px solid #ddd;
}
?
main div:nth-child(1) {
?
background: #5352ed;
}
?
main div:nth-child(2) {
?
background: #ff4757;
}
?
main:hover div:nth-child(1) {
/* 一组帧的名字 可以使用多组帧*/
animation-name: size-percentage;
/* 动画时长 */
animation-duration: 2s;
/* 将动画停留在最后一帧 */
animation-fill-mode: forwards;
?
}
?
main:hover div:nth-child(2) {
/* 一组帧的名字 可以使用多组帧*/
animation-name: size-px;
/* 动画时长 */
animation-duration: 2s;
/* 将动画停留在最后一帧 */
animation-fill-mode: forwards;
?
}
?
?
@keyframes size-percentage {
?
from {
width: 200px;
height: 200px;
}
?
/* px 与 % 之间没有中间值,所以是瞬间出现 */
?
to {
width: 50%;
height: