过渡和动画
在不使用flash或者JavaScript的情况下做出元素的规律运动的效果,可以使页面变得非常丰富,表现力强。
1 . 过渡 transition
使元素由一种样式变成另一种样式:
为变化添加过程与效果。
transition是一个复合属性:
1.1. 过渡属性常用分样式
1.1.1 过渡属性 transition-property:
规定过渡作用在元素的哪条样式上
过渡属性值:
none: 没有过渡属性(清除)
all: 对所有可能样式生效(默认值)
attr 样式属性名, 多个属性以逗号分隔
<style>
*{margin:0;padding:0;}
.box{
width:300px;
height:100px;
background-color: green;
font-size:50px;
color:#fff;
transition-property:font-size;
}
.box:hover{
background-color: red;
color:#000;
font-size:20px;
}
</style>
<div class="box">
hello
</div>
1.1.2 过渡时间 transition-duration:
规定属性发生变化的过渡时间
默认值是0,不写时长等于看不到效果
单位秒(s)和毫秒(ms)
transition-duration:5s;
1.1.3 过渡延迟 transition-delay:
过渡开始前的等待时间, 不计入过渡时间中
注意: transition-delay在恢复也生效
单位秒(s)和毫秒(ms)
transition-delay:5s;
1.1.4 过渡效果的速率(速度变化) transition-timing-function:
过渡时间的速度函数
常见值(关键词):
ease;先慢后快后慢(默认值)
linear;匀速
ease-in; 匀加速
ease-out; 匀减速
ease-in-out; 慢入慢出
特殊值(贝塞尔曲线)
一个带参数的曲线,用于描述运动速度的变化,可以非常精确自由方便的控制变化速率
cubic-bezier(x1,y1,x2,y2);
x1
起点在x轴的坐标 为0-1y1
起点在y轴的坐标 不限x2
终点在x轴的坐标 为0-1x2
终点在x轴的坐标 为0-1
起点对应的 y=x 为匀速,y>x 为加速,y<x 为减速 终点对应的 y=x 为匀速,y>x 为减速,y<x 为加速
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.father {
margin: 60px auto;
position: relative;
width: 600px;
height: 300px;
background-color: #f3f3f3;
}
.father .box {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: skyblue;
transition-delay: 1s;
transition-duration: 5s;
transition-property: all;
transition-timing-function: cubic-bezier(0, .95, .26, .93);/*贝塞尔曲线*/
}
.father:hover .box {
left: 500px
}
</style>
</head>
<body>
<div class="father">
<div class="box">
大家好
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.wrap {
width: 900px;
margin: 50px auto;
background-color: #ccc;
}
.wrap li {
position: relative;
margin-bottom: 20px;
list-style: none;
left: 0;
width: 200px;
height: 100px;
background-color: green;
font-size: 20px;
color: #fff;
transition-property: left;
transition-duration: 5s;
transition-delay: 1s;
}
.wrap li.linear {
transition-timing-function: linear;
}
.wrap li.ease {
transition-timing-function: ease;
}
.wrap li.ease-in {
transition-timing-function: ease-in;
}
.wrap li.ease-out {
transition-timing-function: ease-out;
}
.wrap li.ease-in-out {
transition-timing-function: ease-in-out;
}
.wrap:hover li {
left: 700px;
}
</style>
</head>
<body>
<ul class="wrap">
<li class="linear">linear匀速</li>
<li class="ease">ease慢快慢</li>
<li class="ease-in">ease-in慢入</li>
<li class="ease-out">ease-out慢出</li>
<li class="ease-in-out">ease-in-out慢入慢出</li>
</ul>
</body>
</html>
1.1.5 多属性过渡
多属性过渡注意顺序关系
<style>
*{margin:0;padding:0;}
.wrap{
width:900px;
margin:50px auto;
background-color: #ccc;
}
.wrap li{
position:relative;
margin-bottom:20px;
list-style:none;
left:0;
width:200px;
height:100px;
background-color: green;
font-size:20px;
color:#fff;
transition-property:left,font-size;
transition-duration:5s,2s;
transition-delay:5s,2s;
}
.wrap li.linear{
transition-timing-function:linear,ease;
}
.wrap li.cubic-bezier{
transition-timing-function: cubic-bezier(0.295, 0, 0.285, 0),linear;
}
.wrap:hover li{
left:700px;
font-size:12px;
}
</style>
<ul class="wrap">
<li class="linear">linear匀速</li>
<li class="cubic-bezier">cubic-bezier</li>
</ul>
1.2. 过渡复合样式
复合写法只写transition:
transition: 过渡属性 过渡时间 过渡延迟 过渡效果的速率;
transition: property duration delay timing-function;
单样式过渡复合样式
transtion: left 2s 1s linear
多样式过渡复合样式
transition:width 2s 1s linear,height 4s;
注意:
只有时长不可省略,省略时间就是瞬间完成了
1.3 动画运动完毕后触发事件
- Webkit内核: obj.addEventListener('webkitTransitionEnd',function(){},false);
- firefox: obj.addEventListener('transitionend',function(){},false);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
position: relative;
left: 0px;
top: 0px;
width: 100px;
height: 100px;
background: red;
transition: left 2s linear, background-color 1s linear;
/**/
}
</style>
</head>
<body>
<div class="box"></div>
<script>
var oBox = document.getElementsByClassName("box")[0];
oBox.onclick = function () { //点击时left改变了
oBox.style.left = "500px";
}
oBox.addEventListener("webkitTransitionEnd", function () { //left达到500以后就触发
this.style.backgroundColor = "blue";
});
oBox.addEventListener("transitionend", function () { //left达到500以后就触发transitionend事件
this.style.backgroundColor = "blue";
});
</script>
</body>
</html>
2. 动画 animation
使用过渡属性实现过渡效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.wrap {
position: relative;
width: 700px;
height: 500px;
background-color: #f3f3f3;
margin: 20px auto;
}
.wrap .box {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: skyblue;
transition: 3s;
}
.wrap:hover .box {
left: 600px;
top: 400px;
}
</style>
</head>
<body>
<div class="wrap">
<div class="box"></div>
</div>
</body>
</html>
使用动画实现过渡效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.wrap {
position: relative;
width: 700px;
height: 500px;
background-color: #f3f3f3;
margin: 20px auto;
}
.wrap .box {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: skyblue;
/* transition: 3s; */
}
/*
.wrap:hover .box {
left: 600px;
top: 400px;
} */
.wrap:hover .box {
animation: run 3s;
/*动画3s运行完*/
}
@keyframes run {
/* 定义动画 */
0% {
left: 0;
top: 0;
}
100% {
left: 600px;
top: 400px;
}
}
</style>
</head>
<body>
<div class="wrap">
<div class="box"></div>
</div>
</body>
</html>
transition只能描述开始与结束的变化过程,animation能精确控制各种时间进程的状态。
注意:animation(使用)必须与@keyframes(定义)一起使用
animation是复合属性
2.1. @keyframes
定义动画
写法:
@keyframes animationname{
keyframes-selector{css-style}
}
- animationname`:自定义动画名称
-
keyframes-selector
:动画时长百分比(关键帧)- 0%-100%(在之间需要执行什么事件)
- from(0%) to(100%) 可以只有to
-
Css-style
:一个或多个合法的css
属性
动画示例:
@keyframes run{
0%{width:0px,background:red;}
100%{width:50px,background:green;}
}
/*如果只有起点和终点, 可以使用关键字form to定义动画 ,*/
@keyframes run{
from{width:0px,background:red;}
to{width:50px,background:green;}
}
动画的起始位置不一定就是元素默认位置,可以是其他的值
@keyframes run {
from {
left: 100px;
top: 10s0px;
}
to {
left: 600px;
top: 400px;
}
}
动画的起始位置就是元素出生的位置,初始值 可以省略,直接写to或100%
@keyframes run {
to {
left: 600px;
top: 400px;
}
}
动画上还有其他节点
@keyframes run {
0% {
left: 0;
top: 0;
}
50% {
left: 600px;
top: 0;
}
100% {
left: 600px;
top: 400px;
}
}
当帧动画一样的时候: 例如:
@keyframes run {
0%{width:0px,background:red;}
20%{width:0px,background:red;}
80%{width:500px,background:greend;}
100%{width:500px,background:greend;}
}
可以不同节点样式相同可以采用组合写法
@keyframes run {
0%,20%{width:0px,background:red;}
80%,100{width:500px,background:greend;}
}
2.2. 动画属性的分样式
2.2.1 动画的名称(自定义的) animation-name
调用自定义动画名称
none:不引用任何动画名称
@keyframes绑定的名称
<style>
*{margin:0;padding:0;}
.wrap{
background-color: #ccc;
height:500px;
width:800px;
margin:50px auto;
}
.wrap li{
position: relative;
left:0;
list-style:none;
width:100px;
height:100px;
background-color: green;
animation-name:fun;/* 调用动画 */
}
/*定义动画*/
@keyframes fun{
0%{left:0;}
100%{left:600px;}
}
</style>
<ul class="wrap">
<li></li>
</ul>
注意:如果只使用动画,没有动画运行时间,是看不到动画效果的
2.2.2 动画执行时间 animation-duration
单位秒(s)和毫秒(ms)
animation-duration:2s;
2.2.3 延迟执行时间 animation-delay
动画延时,单位秒(s)和毫秒(ms)
animation-delay:1s;
2.2.4 动画速度曲线 animation-timing-function:
常见值(关键词):
- ease;先慢后快后慢(默认值)
- linear;匀速
- ease-in; 匀加速
- ease-out; 匀减速
- ease-in-out; 快->慢->快
- cubic-bezier() 贝塞尔曲线
特殊值(贝塞尔曲线)
一个带参数的曲线,用于描述运动速度的变化,可以非常精确自由方便的控制变化速率
cubic-bezier(x1,y1,x2,y2);
类似于transition-timing-function
animation-timing-function:ease-in;
2.2.5 动画执行次数 animation-iteration-count ,过渡是没有次数的
n 次数数值(默认一次)
infinite(关键词,无限重复次数)
animation-iteration-count:2;
2.2.6 执行方向 animation-direction:
多次运动才能出发此效果
属性值:
- normal 正常播放,结束后会回到起点,默认
- reverse: 反向播放,和normal相反
- alternate 播放结束之后反向回到开头,偶数次反向
- alternate-reverse:先反后正,和alternate相反
animation-direction:reverse;
/* 动画属性汇总 */
.wrap:hover .box {
animation-name:run;/* 调用动画 */
animation-duration:2s; /*动画运行时间*/
animation-delay:1s;/*动画延迟时间,无限次执行动画时,只有第一次执行会延迟*/
animation-timing-function:ease-in;/*动画速率*/
animation-iteration-count:infinite;/*动画执行次数*/
animation-direction: alternate-reverse;/* 动画方向 */
}
2.2.7 动画执行状态 animation-play-state:
属性值:
- paused 暂停动画(在运动的元素状态转换成paused时停止动画)
- running 运行动画(停止状态换成running状态会继续动转画)
.wrap:hover li{
animation-play-state:paused;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.wrap {
position: relative;
width: 700px;
height: 500px;
background-color: #f3f3f3;
margin: 20px auto;
}
.wrap .box {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background-color: skyblue;
animation-name: run;
animation-duration: 2s;
animation-delay: 1s;
animation-timing-function: ease-in;
animation-iteration-count: infinite;
animation-direction: alternate-reverse;
}
.wrap:hover .box {
animation-play-state: paused;
/*打开页面动画就是运行的,鼠标移入动画变为停止状态*/
}
@keyframes run {
0% {
left: 0;
top: 0;
}
50% {
left: 600px;
top: 0;
}
100% {
left: 600px;
top: 400px;
}
}
</style>
</head>
<body>
<div class="wrap">
<div class="box"></div>
</div>
</body>
</html>
2.2.8 动画结束之后的状态 animation-fill-mode:
只能运用于结束动画之后
属性值:
- none 默认 原始状态>动画>原始状态
- forwards 原始状态>动画>停在动画帧100%
- backwards (忽略原始状态)进入动画帧0%>动画>原始状态
- both (忽略原始状态)进入动画帧0%>动画>停在动画帧100%
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.wrap {
position: relative;
width: 800px;
height: 500px;
background-color: #f3f3f3;
margin: 100px auto;
list-style: none;
}
.wrap li {
position: absolute;
left: -100px;
top: -100px;
width: 100px;
height: 100px;
background-color: skyblue;
}
.wrap:hover li {
animation-name: run;
/* 调用动画 */
animation-duration: 5s;
/*动画运行时间*/
animation-delay: 3s;
/*动画延迟时间,无限次执行动画时,只有第一次执行会延迟*/
animation-timing-function: linear;
/*动画速率*/
animation-iteration-count: 2;
/*动画执行次数*/
animation-direction: normal;
/*方向*/
animation-play-state: running;
/*状态*/
animation-fill-mode: both;
/*none在原始状态延迟等待,最后回到原始backwards位置
forwards在原始状态延迟等待,最后停留在100%位置
backwards瞬间在动画开始位置延迟等待,最后回到原始位置
both瞬间在动画开始位置延迟等待,最后停留在100%位置
*/
}
@keyframes run {
0% {
left: 0;
top: 0;
}
25% {
left: 700px;
top: 0;
}
50% {
left: 700px;
top: 400px;
}
75% {
left: 0px;
top: 400px;
transform: translate(0%, 0%);
}
100% {
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
</style>
</head>
<body>
<ul class="wrap">
<li></li>
</ul>
</body>
</html>
2.3. 动画的复合样式
复合写法的属性为animation
复合写法:animation: name duration [delay]
[timing-function]
[iteration-count]
[direction]
[play-state]
[fill-mode]
;
单动画写法
animation: run 5s 3s linear 2 normal running both;
/*动画名称,动画时间,[动画延迟],[动画速率],[动画次数],[动画方向],[动画状态],[动画结束后的状态]*/
多动画写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.wrap {
position: relative;
width: 800px;
height: 500px;
background-color: #f3f3f3;
margin: 100px auto;
list-style: none;
}
.wrap li {
position: absolute;
left: -100px;
top: -100px;
width: 100px;
height: 100px;
background-color: skyblue;
}
.wrap:hover li {
animation: run 5s 3s linear 2 normal running both, changeBackground 13s linear; /*多动画复合写法*/
}
@keyframes run {
0% {
left: 0;
top: 0;
}
25% {
left: 700px;
top: 0;
}
50% {
left: 700px;
top: 400px;
}
75% {
left: 0px;
top: 400px;
transform: translate(0%, 0%);
}
100% {
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
@keyframes changeBackground {
0% {
background-color: skyblue;
}
100% {
background-color: red;
}
}
</style>
</head>
<body>
<ul class="wrap">
<li></li>
</ul>
</body>
</html>