什么是缓动function?
在animation的上下文中,缓动函数是什么意思。 似乎dojo,jquery,silverlight,flex和其他UI系统都有缓动function的概念。 我找不到放松function的好解释? 任何人都可以解释一下easing函数的概念,或者对它们进行一个很好的解释,我对这个概念没有兴趣,而不是在框架的具体细节上?
是放宽严格用于位置,还是一般的,可以应用于任何物体的属性?
缓动函数通常是描述给定完整百分比的属性值的函数。 不同的框架使用稍微不同的变体,但是一旦你明白了,这个概念很容易理解,但是最好看一些例子。
首先让我们看看我们所有的cachingfunction将遵循的界面。
我们的宽松函数将会有几个参数:
- percentComplete:(
0.0
到1.0
)。 - elaspedTime:animation运行的毫秒数
- startValue:开始的值(或完成百分比为0%的值)
- endValue:结束时的值(或完成百分比为100%时的值)
- totalDuration:animation的总期望长度,以毫秒为单位
并将返回一个数字,表示属性应该设置的值。
注意:这是jQuery使用其缓动function的相同签名,我将借用示例。
最容易理解的是线性缓解:
var linear = function(percent,elapsed,start,end,total) { return start+(end-start)*percent; }
现在把这个使用:
比方说,我们有一个animation,将要去1000毫秒,应该从0开始,并在50结束。将这些值传递到我们的缓动函数应该告诉我们实际值应该是什么:
linear(0, 0, 0,50, 1000) // 0 linear(0.25, 250, 0, 50, 1000) // 12.5 linear(0.5, 500, 0, 50, 1000) // 25 linear(0.75, 750, 0, 50, 1000) // 37.5 linear(1.0, 1000, 0, 50, 1000) // 50
这是一个非常简单的(无双关语)补间。 这是一个简单的线性插值。 如果你要绘制数值与时间的关系,那将是一条直线:
让我们来看看更复杂一点的缓动function,
var easeInQuad = function (x, t, b, c, d) { return c*(t/=d)*t + b; }
让我们看看相同的结果,使用与以前相同的input:
easeInQuad(0, 0, 0, 50, 1000) // 0 easeInQuad(0.25, 250, 0, 50, 1000) // 3.125 easeInQuad(0.5, 500, 0, 50, 1000) // 12.5 easeInQuad(0.75, 750, 0, 50, 1000) // 28.125 easeInQuad(1, 1000, 0, 50, 1000) // 50
注意这些值与我们的线性缓和值非常不同。 它开始非常缓慢,然后加速到结束点。 在animation完成50%时,它只能达到12.5的值,这是我们指定的start
和end
值之间的实际距离的四分之一。
如果我们要绘制这个函数,它会看起来像这样:
现在让我们看看一个基本的缓解:
var easeOutQuad = function (x, t, b, c, d) { return -c *(t/=d)*(t-2) + b; };
这基本上做了一个缓和的“相反”的加速曲线。它开始快速,然后减速到其结束值:
然后有一些function可以让你轻松进出:
var easeInOutQuad = function (x, t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t + b; return -c/2 * ((--t)*(t-2) - 1) + b; };
这个function将开始缓慢,并结束缓慢,在中间达到其最大速度。
有一些可以使用的缓动/插值:Linear,Quadradic,Cubic,Quart,Quint,Sine。 还有像Bounce和elastic这样的特殊宽松function,有自己的function。
例如,弹性易于:
var easeInElastic = function (x, t, b, c, d) { var s=1.70158;var p=0;var a=c; if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; if (a < Math.abs(c)) { a=c; var s=p/4; } else var s = p/(2*Math.PI) * Math.asin (c/a); return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*ds)*(2*Math.PI)/p )) + b; },
也许其他人可以解释插值背后的实际math部分,因为老实说,我不是一个math知识。 但这是宽松职能本身的基本原则。
当您开始补间/animation时,animation引擎会记住您想要的开始和结束值。 然后每次更新,它的数字已经过了多less时间。 它使用值调用提供的缓动函数来计算属性应该设置的值。 只要所有的缓动函数都实现了相同的签名,就可以轻松地将其换出,核心animation引擎不必知道区别。 (这是一个很好的问题分离)。
你会注意到我避免明确地谈论x
和y
位置,因为放松本身并没有特别的位置。 缓动函数只是定义了开始值和结束值之间的转换。 这些可以是x
坐标,也可以是颜色,也可以是对象的透明度。
实际上,理论上可以应用不同的缓动函数来插入不同的属性。 希望这有助于阐明基本的想法。
这里有一个非常酷的例子 (它使用了一个稍微不同的签名,但是是同一个主体)来玩弄缓解与定位相关的想法。
编辑
这里有一个小小的jsFiddle我扔在一起来演示一些JavaScript的基本用法。 请注意, top
属性使用反弹进行补间,而left
属性使用四边形进行补间。 使用滑块来模拟渲染循环。
由于easing
对象中的所有函数都具有相同的签名,因此可以将它们中的任何一个互换。 现在,这些东西中的大部分都是硬编码的(比如开始和结束值,使用的补间函数以及animation的长度),但是在一个真实世界的animation助手的例子中,你会想要通过在以下属性中:
- 要更改的财产
- 起始值(或者如果
undefined
则使用其当前值) - 最终值
- animation的长度
- 要使用的补间函数的引用。
animation引擎将在animation持续时间内跟踪这些设置,并在每个更新周期中使用补间参数来计算属性新值。
缓动function是一种控制animation速度以达到所需效果(反弹,放大和缩小等)的algorithm。
看看MSDN有什么关于他们的一些细节。
尽pipe它有一个可以接受的答案,但我仍想回答这个老问题。 32bitkid做了必要的解释。 我要补充的是基本的实际执行,因为我找不到一个(我也发布了一个关于它的问题 )。
以这个简单的线性animation为例。 由于代码是不言自明的,我怀疑它需要任何解释。 我们计算一个不随时间变化的恒定增量值,在每次迭代时,我们增加框的位置。 我们直接修改位置variables,然后将其应用于框中。
的jsfiddle
var box = document.getElementById("box"); var fps = 60; var duration = 2; // seconds var iterations = fps * duration; // 120 frames var startPosition = 0; // left end of the screen var endPosition = window.innerWidth - box.clientWidth; // right end of the screen var distance = endPosition - startPosition; // total distance var posIncrement = distance / iterations; // change per frame var position = startPosition; // current position function move() { position += posIncrement; // increase position if (position >= endPosition) { // check if reached endPosition clearInterval(handler); // if so, stop interval box.style.left = endPosition + "px"; // jump to endPosition return; // exit function } box.style.left = position + "px"; // move to the new position } var handler = setInterval(move, 1000/fps); // run move() every 16~ millisecond
body { background: gainsboro; } #box { width: 100px; height: 100px; background: white; box-shadow: 1px 1px 1px rgba(0,0,0,.2); position: absolute; left: 0; }
<div id="box"></div>
这是一个属性(大小,形状,位置)从一个状态转换到另一个状态。
这里有一些整洁的小图来描述jQuery UI提供的缓动function。
在现实生活中认为不像电脑一样工作。 不要认为你的女朋友马上就会爱你,而是立刻就认为你不会假装你的女朋友会爱你。 所以科学家和电脑人(谁不了解你的女朋友)发明了缓和function。 这就像直接应用或切换animation一样。 所以,如果从左向右移动一个矩形,它不像机器人那样移动:“开始,以恒定速度移动,立即停止”,而是“开始,不断地加速,不断降低速度,最终停止”。 所以缓动就像让一些animation,函数,对象或者东西在现实生活中performance得像东西一样。 每种缓和效果都定义了一种行为,这就是为什么我们有“弹性”,“弹跳”缓和效果等等。