网页设计经常会用到各种动画效果.
现实世界的大多数运动都是变速的.与变速运动相比,匀速运动就显得很生硬,给人一种不自然的感觉.
css可以用timing-function参数来实现变速运动.
但不是所有的动画都能用css来解决, 例如下拉刷新, 要用js来根据touchmove的距离来绘制动画效果.
这时就可以用缓动公式来实现各种动画效果.
线性运动(linear)
线性运动的计算公式为: f(x) = x
将线性运动映射到横向移动上,每次移动的距离都是相等的
具体的代码如下:
- currentTime 当前时间
- duration 动画时长
- startValue 起始位置
- changeValue 总移动距离
1 | function linear(currentTime, startValue, changeValue, duration) { |
对应到坐标轴上, currentTime是x轴上某点(记为点a), duration是x轴长度,startValue和changeValue分别是y轴起点和长度.返回值是点a对应的y轴坐标.
缓入(ease-in)
开始时速度很慢, 然后逐渐加快.结尾会突然停止,感觉很生硬.
缓入的计算公式为: f(x) =x * x
将ease-in映射到横向移动上,可以观察到开始很慢, 然后逐渐变快, 在结尾时速度最快.
具体的代码如下:
1 | function easeInQuad(currentTime, startValue, changeValue, duration) { |
上面代码的执行步骤为:
- 将"当前时间"映射[0, 1]间(currentTime /= duration)
- 根据缓入公式计算出"当前时间"应该移动的百分比(currentTime * currentTime)
- 根据"总移动长度"和"移动百分比"算出应移动的具体值(changeValue * ...)
- 加上初始位置(+ startValue)
函数名easeInQuad中Quad指的是二次方, 也就是乘两次.
其它的easeIn函数还有easeInCubic(x^3), easeInQuart(x^4), easeInQuint(x^5).
乘的次数越多, 速度变化的幅度越大.
缓出(ease-out)
常用的变速运动, 开始时速度很快,给人一种流畅感.然后逐渐减速, 不会让人觉得戛然而止.
缓出的计算公式为: f(x) = -xx+2x
其实就是ease-in函数的镜像翻转
将ease-out映射到横向移动上,可以观察到开始时速度最快, 然后逐渐变慢,在结尾时速度最慢.
具体的代码如下:
1 | function easeOutQuad(currentTime, startValue, changeValue, duration) { |
缓入缓出(ease-in-out)
开始和结尾慢时, 中间快.比缓出更生动.
动画时间不宜过长, 最好在300~500ms间.
ease-in-out和ease非常相似,不同点在于ease的开始速度比结束速度更快一些.
ease-in-out是ease-in和ease-out的结合,前半段用ease-in的计算公式,后半段用ease-out的计算公式.
将ease-in-out映射到横向移动上,可以观察到开始速度慢, 然后逐渐变快,到中间时达到最大值, 然后又逐渐减慢.
具体的代码如下:
1 | easeInOutQuad(currentTime, startValue, changeValue, duration) { |
上面代码的执行步骤为:
- 将当前时间映射到[0, 2]间(currentTime /= duration / 2)
- 如果"当前时间"小于1, 则用ease-in公式计算.除2是因为y轴(总长度)实际上只有一半,后面一半用ease-out计算.
- 如果"当前时间"大于等于1,则用ease-out公式计算
其他运动效果
还有很多复杂的过渡函数,访问如下的网站来查询更多的过渡函数及效果
附录
过渡函数曲线
See the Pen easing function(x,y) by aaronbird (@aaronbird) on CodePen.
横向移动速度
See the Pen easing function by aaronbird (@aaronbird) on CodePen.
参考
缓动公式小析
https://developers.google.com/web/fundamentals/design-and-ux/animations/the-basics-of-easing?hl=zh-cn
如何使用Tween.js各类原生动画运动缓动算法 « 张鑫旭-鑫空间-鑫生活