首先我们先了解animation这个属性的语法格式:
//语法:
animation:动画名称 动画时间 运动曲线 何时开始 播放次数 是否反方向;
/*
默认情况下,动画执行完毕都会恢复原样
参数1:动画名
参数2:动画持续时间
参数3:延迟时间
参数4:动画曲线 steps linear这些
参数5:动画次数
参数6:是否恢复原样,默认为恢复,加一个forwards就代表不恢复(就变成动画最终的样子)
参数7:alternate:加这个东西就代表让元素恢复的时候也有动画效果
恢复的时候也算一次动画,所有如果为2,那么一次到动画目的一次返回就没了
normal:默认值就是用动画效果到最终目的
reverse:先闪现最终目的,再用动画效果回到最初的值
alternate-rever:相当于就是reverse,只是比reverse多了一个动画恢复
关于几个值,除了名字,动画时间,延时有严格顺序要求其它随意.
*/
为了实现动画所以必须准备一个动画剧本:
//规定动画语法:from...to...定义的是从开始到结束两个状态
@keyframes 动画名称 {
from{ 开始位置 } 0%
to{ 结束 } 100%
}
//规定各个阶段不同的状态的动画(不只有开始于结束状态)
@keyframes 动画名称 {
0% { }
n1% { }
n2% { }
n3% { }
n4% { }
.........
100% { }
}
比如下面的例子用来规定一个动画:
@keyframes goback {
0%{}
49%{
transform: translateX(1000px);
}
55%{
transform: translateX(1000px) rotateY(180deg);
}
95%{
transform: translateX(0) rotateY(180deg);
}
100%{
transform: translateX(0) rotateY(0deg);
}
}
//在规定动画的时候,可以有多个过程节点用来描述动画的状态.
//上面的例子中:goback动画就是在不同的时间点位置不同.
第二:注重介绍:animation-timing-function是控制时间的函数:
在取值中除了常用到的 三次贝塞尔曲线 以外,还有个让人比较困惑的 steps() 函数
animation默认以ease方式过渡,它会在每个关键帧之间插入补间动画,所以动画效果是连贯性的
除了ease,linear、cubic-bezier之类的过渡函数都会为其插入补间。但有些效果不需要补间,只需要关键帧之间的跳跃,这时应该使用steps过渡方式
animation-timing-function 规定动画的速度曲线
以上w3school网站上给的使用方法,但是漏掉一个很重要的 steps
简单的来说,我们一直使用animation基本都是实现线性渐变的动画
如:
位置在固定的时间从起点到终点
尺寸在固定的时间线性变化
颜色的线性改变等等
理解steps
//steps 函数指定了一个阶跃函数
//第一个参数指定了时间函数中的间隔数量(必须是正整数)
//第二个参数可选,接受 start 和 end 两个值,指定在每个间隔的起点或是终点发生阶跃变化,默认为 end。
step-start等同于steps(1,start),动画分成1步,动画执行时为开始左侧端点的部分为开始;
step-end等同于steps(1,end):动画分成一步,动画执行时以结尾端点为开始,默认值为end。
/*
steps第一个参数的错误的理解:
steps(5,start)
steps() 第一个参数 number 为指定的间隔数,即把动画分为 n 步阶段性展示,估计大多数人理解就是keyframes写的变化次数
*/
例如:
@keyframes circle {
0% {}
25%{}
50%{}
75%{}
100%{}
}
我之前也一直认为steps(5,start)中的5 就是指的keyframes中的0% 25% 50% 75% 100% 分成5个间隔等分
为什么会出现这种理解错误,我们看一个例子
keyframes的关键帧是只有2个规则的时候,假如我们有一张400px长度的雪碧图
@keyframes circle {
0% {background-position-x: 0;}
100%{background-position-x: -400px;}
}
此刻设置steps(5,start)那么会发现5张图会出现帧动画的效果,因为steps中的5把 0% – 100%的规则,内部分成5个等分,实际内部会执行这样一个关键帧效果:
@keyframes circle {
0% {background-position-x: 0;}
25% {background-position-x: -100px;}
50% {background-position-x:-200px;}
75%{background-position-x: -300px;}
100%{background-position-x: -400px;}
}
将这个规则稍微修改下,加入一个50%的状态
@keyframes circle {
0% {background-position-x: 0;}
50% {background-position-x: -200px;}
100%{background-position-x: -400px;}
}
那么同样用steps(5,start)效果就会乱套
此刻你会很迷惑,所以关键要理解第一个参数的针对点,首先引入一个核心点:
**timing-function 作用于每两个关键帧之间,而不是整个动画**
那么第一个参数很好理解了,steps的设置都是针对两个关键帧之间的,而非是整个keyframes,所以第一个参数对 - 次数对应了每次steps的变化,换句话说也是 0-25 之间变化5次, 25-50之间 变化5次 ,50-75 之间变化5次,以此类推.
第二个参数可选,接受 start 和 end 两个值,指定在每个间隔的起点或是终点发生阶跃变化,默认为 end
通过案例看下 step-start,step-end 的区别
@keyframes circle {
0% {background: red}
50%{background: yellow}
100% {background: blue}
}
/*
step-start : 黄色与蓝色相互切换
step-end : 红色与黄色相互切换
2个参数都会选择性的跳过前后部分,start跳过0%,end跳过100%
*/
step-start在变化过程中,都是以下一帧的显示效果来填充间隔动画,所以0% 到 50% 直接就显示了黄色yellow
/*
一定要记住:steps()的变化时帧变化,即第一帧直接到第二帧再到下一帧,
这跳转的过程是不会补间的(不会来填充帧与帧之间的变化过程),可以理解
为两幅图片之间的无缝切换
*/
引用w3c的一张step的工作机制图
总结:
steps函数,它可以传入两个参数,第一个是一个大于0的整数,他是将间隔动画等分成指定数目的小间隔动画,然后根据第二个参数来决定显示效果。
第二个参数设置后其实和step-start,step-end同义,在分成的小间隔动画中判断显示效果。可以看出:steps(1, start) 等于step-start,steps(1,end)等于step-end
最核心的一点就是:
timing-function 作用于每两个关键帧之间,而不是整个动画.
案例:
好了上面介绍了animation的使用,那么现在就来实现小黄鸭的功能:
一、需求:在页面上显示小黄鸭的眨眼闭眼的效果
二、利用下载好的雪碧图来改变大background-position的位置不同,再通过动画来实现此功能。
三、https://game.gtimg.cn/images/mxd2/web201707/download-icon-spr.png图片可以去这里下载。
上面时定义好了每一帧之间只有一次动画展示,那么也可以在两个关键帧之间展示分多个阶段来展示:
.rubberDuck {
width: 266px;
height: 227px;
margin: 100px auto;
background: url(./img/download-icon-spr.png)
no-repeat -10px 0;
/*将代码修改成这样也可以实现功能,
在哪个相当于在定义的两个关键帧之间
进行13步来展示*/
animation: da 1.3s steps(13) infinite;
}
@keyframes da{
0% { }
76.7%, 82.6%, 88.5%, 94.4%, 100% {
background-position-y: -2951px
}
}
二.实现动画的由远及近(呼吸动画)的效果
基本的语法知识:
过渡(transition)是CSS3中具有颠覆性的特征之一,我们可以在不使用 Flash 动画或 JavaScript 的情况下,当元素从一种样式变换为另一种样式时为元素添加效果。
在CSS3里使用transition可以实现补间动画(过渡效果),并且当前元素只要有“属性”发生变化时即存在两种状态(我们用A和B代指),就可以实现平滑的过渡。记住这里是补间动画。上面的是关键帧之间的跳跃的动画。
语法格式:
/*transition: 要过渡的属性 花费时间 运动曲线 何时开始;*/
/*如果有多组属性变化,还是用逗号隔开。*/
2D变形(CSS3) transform
//1.translate属性
// translate(x,y)水平方向和垂直方向同时移动(也就是X轴和Y轴同时移动)
// translateX(x)仅水平方向移动(X轴移动)
// translateY(Y)仅垂直方向移动(Y轴移动)
.box {
width: 499.9999px;
height: 400px;
background: pink;
position: absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%); /* 走的自己的一半 */
}
//2. scale()的取值默认的值为1,当值设置为0.01到0.99之间的任何值,作用使一个
// 元素缩小;而任何大于或等于1.01的值,作用是让元素放大
scale(X,Y)使元素水平方向和垂直方向同时缩放(也就是X轴和Y轴同时缩放)
scaleX(x)元素仅水平方向缩放(X轴缩放)
scaleY(y)元素仅垂直方向缩放(Y轴缩放)
// scale()的取值默认的值为1,当值设置为0.01到0.99之间的任何值,作
//用使一个元素缩小;而任何大于或等于1.01的值,作用是让元素放大
//3 旋转 rotate(deg)可以对元素进行旋转,正值为顺时针,负值为逆时针;
transform:rotate(45deg);
3D变形(CSS3) transform
//三维坐标:
// x左边是负的,右边是正的
// y 上面是负的, 下面是正的
// z 里面是负的, 外面是正的
/*
1.translate属性
translate(x,y,z)水平方向和垂直方向同时移动(也就是X轴和Y轴同时移动)
translateX(x)仅水平方向移动(X轴移动)
translateY(Y)仅垂直方向移动(Y轴移动)
translateZ(z)仅前后方向移动(Z轴移动)
*/
/*
rotateX() 就是沿着 x 立体旋转 上下翻转
rotateY() 沿着y轴进行旋转 左右翻转
rotateZ()沿着z轴进行旋转 顺时针,逆时针
*/
/*
scaleX(x)元素仅水平方向缩放 宽度变化
scaleY(y)元素仅垂直方向缩放 高度变化
scaleZ(Z)元素仅前后方向缩放 无,因为页面中的元素没有厚度
*/
/*
视点:
就是模拟一个镜头距离一个元素的距离拍下来再展现到屏幕,这个很重要,
如果不加那么translateZ在这个效果是看不出来的.
1.设置在每个元素:transform:perspective(距离),每个元素都有视点,
但是不符合生活场景,因为人的眼睛只有一个视点
2.设置在父元素: perspective:距离,符合生活场景
应用原理:近大远小,如果元素参与了旋转,那么不要把视点加在它身上,加在不动的父元素上
*/
/*
transform-style: preserve-3d;开启3D效果
*/
由远及近的效果(呼吸效果)就是在我鼠标移动到图片上时,图片缩放效果为放大效果,即使设置scale()里的值比1大就可以了;当鼠标移出时,设置scale()里的值比1小就可以了。注意这里是利用jQuery来实现功能的
案例:
下面是实现的代码:
Document
效果:
呼吸的另外一种由下到上效果的实现:在联想的官网里面我们发现他的呼吸灯效果是从下到上的实现.具体实现为:
Document
小米官网的呼吸效果的,同样也是运用了这种效果的实现,只不过他给了外层盒子一个shadow的阴影.
上述的代码里面的样式只需要改成这样就可以了: