css3动画

20210108更新

怎么监听css3动画结束后的事件

在执行完一段css3动画后需要进行一些业务操作或者页面操作等等,咋搞呢?

我们可以使用js来监听两个事件

  • 动画播放过程会触发两类事件:
  1. AnimationEvent
  2. TransitionEvent
  • 动画结束的事件的两个实现分别是:
  1. animationend
  2. transitionend

Demo页面在这里,只测试过Chrome

https://codepen.io/longtian/pen/jEyrzN

兼容性大坑可以看AngularUI的这部分源码

https://github.com/angular-ui/bootstrap/blob/7512b93fecb6f27df4f5aeba4c756c0c36aebbf2/src/transition/transition.js#L59

比如监听一个动画结束

1
2
3
4
5
6
<div id="animend" class="floating">animationend</div>

document.getElementById("animend").addEventListener("webkitAnimationEnd", e => {
// todo ...

}, false);

3个重要属性

transform 变形

transform(变形)允许你旋转,缩放,倾斜或平移给定元素

拥有 rotate 旋转 skew 扭曲 scale 缩放 translate 移动 matrix 矩阵变形五大特效

1
2
3
4
5
6
div {
border: solid red;
transform: translate(30px, 20px) rotate(20deg);
width: 140px;
height: 60px;
}
  • 设置变换中心
1
2
3
div {
transform-origin: center bottom;
}

可选值有left top center right bottom

还可以直接写位置50px 50px

scale 缩放

1
2
3
4
5
6
7
8
9
10
11
12
 /*
scale: 缩放
scale(水平放缩比例,垂直放缩比例);
大于1:放大
小于1:缩小
如果只写一个值等比例缩放
*/
div {
transform: scale(1);
transform: scale(0.5);
transform: scale(1, 1.5);
}

translate 平移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
div {
/* translate:(水平位移,垂直位移);
正值:向右向下
负值:向左向上
如果只写一个值 水平移动
百分比 :相对于自身移动
*/

/* Single values */
transform: translate(100px);
transform: translate(50%);

/* Two values */
transform: translate(100px 200px);
transform: translate(50% 105px);
}

skew 倾斜

这个CSS属性定义了在2D平面上一个对象的歪斜变换

1
2
3
4
5
6
7
div {
/* skew(ax, ay) */
/* ax 用于沿横坐标扭曲元素的角度 */
transform: skew(10deg);
/* ay 用于沿纵坐标扭曲元素的角度。如果未定义,则其默认值为0,导致纯水平倾斜 */
transform: skew(10deg, 20deg);
}

rotate X,Y,Z 旋转

图不就不贴了 随便在一个网址上F12改元素的样式就可以看出来效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
div {
/*
rotate
直接旋转

rotateX
上下旋转

rotateY
左右旋转

rotateZ
旋转的
*/
}

rotateZ和rotate看起来效果一样

translate X,Y,Z 平移

1
2
3
4
5
6
7
8
9
body {
/* 透视*/
perspective: 600px;
}

.box:hover {
/* translateZ必须配合透视来使用*/
transform: translateZ(400px);
}

translate和translateX看起来效果一样

transition 过渡

拥有修改执行变换的属性,时长,速率和延迟时间的能力

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
div {
/* Apply to 1 property */
/* property name | duration */
transition: margin-right 4s;

/* property name | duration | delay */
transition: margin-right 4s 1s;

/* property name | duration | timing function */
transition: margin-right 4s ease-in-out;

/* property name | duration | timing function | delay */
transition: margin-right 4s ease-in-out 1s;

/* Apply to 2 properties */
transition: margin-right 4s, color 1s;

/* Apply to all changed properties */
transition: all 0.5s ease-out;

/* Global values */
transition: inherit;
transition: initial;
transition: unset;
}

  • 指定transition效果的转速曲线

指定为一个或多个 CSS 属性的过渡效果,多个属性之间用逗号进行分隔。

transition-timing-function: linear | ease | ease-in | ease-out | ease-in-out | cubic-bezier(n, n, n, n);

描述
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 函数中定义自己的值。可能的值是 0 至 1 之间的数值。
  • 指定动画延迟时间
1
2
3
div {
transition-delay: 0.8s;
}
  • 指定CSS属性的name,transition效果
1
2
3
div {
transition-property: width;
}
  • transition效果需要指定多少秒或毫秒才能完成
1
2
3
div {
transition-duration: 1s;
}

animation 重难点

若将Transform解释为动作,Transition解释为过渡,那么Animation则是连续的几个动作,即动画。Animation可以我们设定keyframes的值,让元素在一段时间内完成多个动作。

语法

animation : name duration timing-function delay iteration-count direction fill-mode play-state animation : 动画名称 持续时间 运动曲线 延迟执行 执行次数 方向 动画结束后元素应该在的位置 动画状态

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
div {
/* animation属性详解*/
/* 动画名称*/
animation-name: move;

/* 一次动画持续时间 前两属性是必须,且顺序固定*/
animation-duration: 3s;

/* 动画执行次数 无数次:infinite*/
animation-iteration-count: 1;

/* 动画的方向: normal 正常 , alternate: 反向*/
animation-direction: alternate;

/* 动画延迟执行*/
animation-delay: 1s;

/* 设置动画结束盒子盒子的状态
forwards:保持动画结束后的状态 backwards:保持动画开始前的状态*/
animation-fill-mode: forwards;

/* 运动曲线 linear ease-in-out steps()*/
/*animation-timing-function:ease-in;*/

animation-timing-function: steps(8);

/* 控制动画状态 paused 暂停 running 播放*/
animation-play-state: paused;
}
描述
animation-name 指定 @keyframes 动画的名称。
animation-duration 指定动画完成一个周期所需要时间,单位秒(s)或毫秒(ms),默认是 0。
animation-timing-function 指定动画计时函数,即动画的速度曲线,默认是 "ease"。
animation-delay 指定动画延迟时间,即动画何时开始,默认是 0。
animation-iteration-count 指定动画播放的次数,默认是 1。
animation-direction 指定动画播放的方向。默认是 normal。
animation-fill-mode 指定动画填充模式。默认是 none。
animation-play-state 指定动画播放状态,正在运行或暂停。默认是 running

关于几个值,除了名字,动画时间,延时有严格顺序要求其它随意

一个例子:

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
41
42
43
44
45
46
47
48
49
50
.box {
width: 200px;
height: 200px;
margin: 100px;
background-color: green;
/* 调用*/
/* infinite:无限次*/
/* animation: 动画名称 持续时间 执行次数 是否反向 运动曲线 延迟执行*/
/*animation: move 1s alternate linear 3 ;*/
animation: gun 4s;
}

/* 定义动画*/
@keyframes move {
from {
transform: translateX(0px) rotate(0deg);
}
to {
transform: translateX(500px) rotate(555deg);
}
}

/* 定义多组动画*/
@keyframes gun {
0% {
transform: translateX(0px) translateY(0px);
background-color: green;
border-radius: 0;
}

25% {
transform: translateX(500px) translateY(0px);
}

50% {
transform: translateX(500px) translateY(300px);
border-radius: 50%;
}


75% {
transform: translateX(0px) translateY(300px);
}

100% {
transform: translateX(0px) translateY(0px);
background-color: red;
border-radius: 0;
}
}

animation-timing-function

常见值有:linear、ease、ease-in、ease-out、ease-in-out

这些值其实都是 cubic-bezier(n,n,n,n) 的特例。它们被称为贝塞尔曲线。

一个在线调试贝塞尔曲线的网站:cubic-bezier.com

animation-fill-mode (重点)

除了默认值 none 外,还有另外 3 个值:

  • forwards,表示,动画完成后,元素状态保持为最后一帧的状态。
  • backwards,表示,有动画延迟时,动画开始前,元素状态保持为第一帧的状态。
  • both,表示上述二者效果都有。

这个贴个图理解一下

举个例子,div 从 100px 处移动到 200px 处的关键帧定义为:

1
2
3
4
5
6
7
8
@keyframes move{
0%{
transform: translate(100px,0);
}
100%{
transform: translate(200px,0);
}
}

设置填充模式为 forwards 时,动画最后停留在 200px 处:

设置动画延迟 1s 后执行,且填充模式为 backwards 时,可以看到动画在开始前是处于 100px 处,动画结束后回到 0px 处:

最后设置填充模式为 both 的情形:

动画结束后,保持动画最后一帧的状态,这个太有用了.

一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
div{
height: 10px;
border: 1px solid;
background: linear-gradient(#0ff,#0ff);
background-repeat: no-repeat;
background-size: 0;
animation: move 2s linear forwards;
}

@keyframes move{
100%{
background-size: 100%;
}
}

animation-delay

不为大家注意的是,延迟可以为负数。负延迟表示动画仿佛开始前就已经运行过了那么长时间。 拿上述进度条为例子,原动画用了 2s 是从 0% 加载到 100% 的。如果设置延迟为 -1s。这动画会从 50% 加载到 100%。仿佛已经运行了 1s 一样:

animation-play-state

CSS 动画是可以暂停的。属性 animation-play-state 表示动画播放状态,默认值 running 表示播放, paused 表示暂停

animation-iteration-count

表示动画播放次数。它很好懂,只有一点要注意,无限播放时使用 infinite

animation-direction

它的意思说指定动画按照指定顺序来播放 @keyframes 定义的关键帧

  • normal 默认值。
  • reverse 表示动画反向播放。
  • alternate 表示正向和反向交叉进行。
  • alternate-reverse 表示反向和正向交叉进行。

这个自己动手在浏览器改下样式更容易理解

最后附带一个代码 css3动画

还有几个参考动画15个CodePen上启发灵感的CSS动画案例

一个动画库AnimateCss

一个动画可视化编辑工具网址AnimationKit


css3动画
https://iplus-studio.top/2020/12/25/css3动画/
作者
邓伟彬
发布于
2020年12月25日
许可协议