利用 CSS3 的 Animation 能够建立动画,在许多页面中可以替代 Flash、JS 等,提高页面加载速度。众所周知,Animation 有 8 大属性,以下所述:函数
属性名 | 简介 |
---|---|
animation-name | 规定须要绑定到选择器的 keyframe 名称 |
animation-duration | 完成动画所花费的时间,以秒或毫秒计 |
animation-timing-function | 规定动画的速度曲线 |
animation-delay | 动画开始前的延迟 |
animation-iteration-count | 动画播放次数 |
animation-direction | 规定是否应该轮流反向播放动画 |
animation-play-state | 指定动画是否正在运行或已暂停 |
animation-fill-mode | 当动画不播放时(动画完成或动画延迟),要应用到元素的样式 |
以上这 8 个属性就决定了 Animation 可以实现一个什么样的动画效果。 动画
本文主要介绍 timing-function
中的steps()
函数。Animation 在执行动画时默认以 ease
函数进行过渡,ease 会在每一个关键帧之间插入补间动画,因此动画效果是连贯的。
除了ease函数以外,linear
和cubic-bezier
(贝塞尔曲线)等过渡函数也会为其插入补间动画。url
但有的时候某些效果不须要补间,只须要在关键帧之间进行跳跃,这时就用到了steps()过渡方式。spa
steps()
是 Animation 中的一个timing-function
函数, 可以实现动画的阶跃式变化,而非两个状态间的线性过渡。 steps()
接收两个参数:3d
steps ( n, [start | end] )
你们都见过很经典的菊花 loading 效果图,其实现原理很简单:
一张静态图片,而后为其添加动画:调试
设定在固定步数内旋转(rotate) 360 度便可实现 loading 效果,具体实现方式以下:
<div> <img class = "loading-dot-step" src="./loading.png"> </div> ... .loading-dot-step { animation: loading 1s infinite steps(12,start); } @keyframes loading { 0% {transform: rotate(0deg);} 100% {transform: rotate(360deg);} }
静态图片如图所示:code
给上面的静态图片添加动画,steps 设定 12 步完成两个关键帧间的动做轨迹,即从当前状态旋转 360 度,实现下面 gif 的动画效果。orm
除了菊花 loading 效果,很常见的还有线性 loading,其实现方式是:
利用 timing-function
的 linear
线性过渡函数,实现图片的连续旋转,此时的效果在视觉上就是连续的动画,以下图所示:cdn
对于两种 loading 效果图,第一种为 steps
方式,第二种为线性过渡
方式。
二者实现原理相似:blog
均在两个关键帧之间将图片从当前状态旋转至 360 度,当 timing-function 设置为 linear 时,从 0% 到 100% 的状态变化为匀速线性变化;
当动做设定为 steps 时,将从 0 度旋转至 360 度的整个动画分为 12 步执行完,且每步之间是跳跃的,所以出现了经典的菊花 loading 效果。
steps 的执行点 start 和 end 是许多人存在疑惑的地方,误用 start 和 end 可能会出现和理想状况下不一致的动画效果,许多人分不清二者的区别在哪里,下面以几个简单的 demo 来辅助理解这两个属性值的区别。
steps()
可简化出 step-start
和 step-end
这两个关键字。
<p>一、steps(1, start)</p> <div class="a box"></div> <p>二、steps(1, end)</p> <div class="b box"></div> ... .a{ animation:changeColor 4s infinite steps(1, start); } .b{ animation:changeColor 4s infinite steps(1, end); } @keyframes changeColor{ 0%{ background-color: red; } 100%{ background-color: blue; } }
上述代码显示效果以下图所示:
一、steps(1, start)
二、steps(1, end)
代码可见,二者设定的均为 1 步执行完动画,实现将 div 的颜色从红色变为蓝色
,可是咱们看到的结果倒是不一样的,这就是因为 start
和 end
两个属性的执行点不一样形成的结果差别。
规范文档中给出了关于 steps()
的函数图,以下图所示:
对比 steps 函数中的 start 和 end 两个执行点,由上图中步数为 1 的两图可见:
一样,当步数等于 3 时,肉眼可见的 start 的执行点为第一步执行结束的位置,end 的执行点则为第一步还没有开始的位置 。因为动画执行的步数相同但起点不一样,所以动画的结束点也不相同,设置为 start 的状况下,结束点为动画结束的最后一步的状态,而 end 为结束前一步的状态。
为了更加直观地展现二者执行的开始点和结束点的区别,本文以横向坐标图的方式对执行过程进行示意:
如今能够解释上述 demo 中两个 div 颜色显示不同的缘由了,对于 steps 属性值为 start 的 a-box,进入画面时动画的第一阶段已经完成,所以咱们不会看到红色,直接显示蓝色;对于 steps 属性值为 end 的 b-box,动画保持第一帧的状态直到结束,所以始终显示为红色。
并不是全部的动画都是连续的,对于某些非连续变化的效果就须要用到 steps 来实现。 例如钟表秒针阶跃式的转动,或者在动画中模仿人物或动物的脚印行走效果,再或者利用雪碧图实现人物跑动的效果等等。下面详细介绍一下人物跑动效果的实现方式。
人物奔跑 demo
<div class="person"></div> ... .person { background: url('person.jpg') no-repeat; background-size: 800%; // 动画名称 持续时间 运动曲线(steps()分为几步)循环次数 animation: personBlast .8s steps(7) infinite; } @keyframes personBlast { 0% { background-position: left; } 100% { background-position: right; } }
其中 person.jpg 为人物动做分割的雪碧图:
本文奔跑动做实现方式为将原始雪碧图进行按图形帧数的倍数放大
,而后设定steps 为雪碧图的帧数减 1(8 帧分为 7 步执行完),关键帧的动做为从 (from) 雪碧图左侧阶跃式跳跃到(to)右侧,最终实现下面的跑动效果:
【 注:此奔跑效果的实现方式不尽相同,此处只是其中一种,这样作是为了让你们更好的理解 steps 的应用场景,还有其余更友好的实现方式欢迎你们一块儿交流 】
对于 Animation 的 timing-function 有一个须要引发注意的点,即:
timing-function 的执行位置为两个关键帧之间,而非整个动画
此处的 timing-function 指的是本文所讲的 steps 函数以及 linear、ease、cubic-bezier 等函数。
这里仍是经过一个简单的 demo 来了解这个点。首先看一下下面的动画效果:
实现代码为:
<div class="test test-a"></div> <div class="test test-b"></div> ... .test-a { animation: changeColorOne 1s steps(1) infinite; } .test-b { animation: changeColorTwo 1s steps(1) infinite; } @keyframes changeColorOne { 0% { background-color: red; } 100% { background-color: blue; } } @keyframes changeColorTwo { 0% { background-color: red; } 25%{ background-color: blue; } 75%{ background-color: red; } 100% { background-color: blue; }
所以:steps 并不是做用于整个动画,而是做用于每两个关键帧之间,与动画的时长、播放次数等都无关,因此整个动画的执行时间仍是 Animation 中设定的 1s。
Animation 时间函数中的 steps() 确实很差理解,可是一旦掌握了它会为咱们的开发工做带来很大的效率提高,节省不少调试时间,也能帮助咱们快速定位问题。 但愿本文的讲解能够帮助你更好的理解和使用 steps()。感谢阅读,欢迎互相交流!