什么是缓动函数? [英] What is an easing function?

查看:50
本文介绍了什么是缓动函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

动画上下文中缓动函数是什么意思.似乎dojo、jquery、silverlight、flex等UI系统都有缓动功能的概念.我找不到缓动函数的一个很好的解释?任何人都可以解释缓动函数的概念,或者对它们进行很好的解释,我对这个概念感兴趣而不是框架的具体细节?

What is meant by easing function in the context of animation. It seems that dojo, jquery, silverlight, flex and other UI systems have the notion of easing function. I could not locate a good explanation of easing functions? Can anyone explain the concept of easing functions, or point a good explanation of them, I am interested in the concept not in the specific details of a framework?

缓动是严格用于位置还是通用并且可以应用于对象的任何属性?

Is easing strictly used for location or is it general and can be applied to any property of an object?

推荐答案

缓动函数通常是描述给定完整性百分比的属性值的函数.不同的框架使用略有不同的变体,但是一旦你有了想法,这个概念就很容易掌握,但最好还是看几个例子.

An easing function is usually a function that describes the value of a property given a percentage of completeness. Different frameworks use slightly different variations, but the concept is easy to grasp once you get the idea, but it's probably best to look a few examples.

首先让我们看一下我们所有缓动函数都遵循的接口.

First lets look at the interface that all our easing functions will abide by.

我们的缓动函数将接受几个参数:

Our easing functions will take several arguments:

  • percentComplete:(0.01.0).
  • elapsedTime:动画运行的毫秒数
  • startValue:起始值(或完成百分比为 0% 时的值)
  • endValue:结束的值(或完成百分比为 100% 时的值)
  • totalDuration:以毫秒为单位的所需动画总长度

并将返回一个数字,该数字表示该属性应设置为的值.

And will return a number which represents the value the property should be set to.

注意:这与 jQuery 用于缓动函数的签名相同,我将借用它作为示例.

Note: this is the same signature that jQuery uses for its easing functions, which I'll be borrowing for examples.

最容易理解的是线性缓动:

The easiest to understand is a linear ease:

var linear = function(percent,elapsed,start,end,total) {
    return start+(end-start)*percent;
}

现在开始使用:

假设我们有一个动画将持续 1000 毫秒,并且应该从 0 开始到 50 结束.将这些值传递给我们的缓动函数应该会告诉我们实际值应该是什么:

Lets say we had an animation that was going to go for 1000 milliseconds and was supposed to start at 0 and end at 50. Passing those values into our easing function should tell us what the actual value should be:

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

这是一个非常直接的(没有双关语意)补间.这是一个简单的线性插值.如果您要绘制价值与时间的关系图,它将是一条直线:

This is a pretty straight forward (no pun intended) tween. It is a simple linear interpolation. If you were to graph value vs time, it would be a straight line:

让我们来看看更复杂的缓动函数,二次缓动:

Lets take a look at a bit more complicated easing function, a quadratic ease in:

var easeInQuad = function (x, t, b, c, d) {
    return c*(t/=d)*t + b;
}

让我们看看相同的结果,使用与之前相同的输入:

And lets look at the same results, using the same inputs as before:

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

请注意,这些值与我们的线性缓动非常不同.它开始非常缓慢,然后加速到终点.在动画完成 50% 时,它仅达到 12.5 的值,这是我们指定的 startend 值之间实际距离的四分之一.

Notice the values are very different than our linear ease. It starts out very slow, then accelerates to its ending point. At 50% completion of the animation it has only made it to a value of 12.5, which is one quarter of the actual distance between the start and end values we have specified.

如果我们要绘制这个函数,它看起来像这样:

If we were to graph this function it would look something like this:

现在让我们来看看基本的缓出:

Now lets take a look at a basic ease-out:

var easeOutQuad = function (x, t, b, c, d) {
    return -c *(t/=d)*(t-2) + b;
};

这本质上是执行缓入的相反"加速曲线.它开始很快,然后减速到其结束值:

This essentially does the "opposite" acceleration curve of an ease in. It starts out fast and then decelerates to its ending value:

还有一些功能可以轻松进出:

And then there are functions that ease both in and out:

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;
};

此函数将开始缓慢结束,在中间达到最大速度.

This function will start out slow and end slow, reaching its maximum velocity in the middle.

您可以使用多种缓动/插值:线性、二次、三次、四分、五分、正弦.还有一些特殊的缓动功能,比如 Bounce 和 elastic,它们都有自己的功能.

There are a bunch of easing/interpolations that you can use: Linear, Quadradic, Cubic, Quart, Quint, Sine. And there are specialty easing functions like Bounce and elastic, which have their own.

例如,弹性缓动:

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*d-s)*(2*Math.PI)/p )) + b;
},

也许其他人可以解释插值背后的实际数学部分,因为老实说,我不是数学奇才.但这是缓动函数本身的基本原理.

Perhaps somebody else can explain the actual math part behind the interpolation, because honestly I'm not a math wiz. But that's the basic principle of the easing functions themselves.

当您开始补间/动画时,动画引擎会记住您想要的开始和结束值.然后每次更新时,它都会计算出已经过去了多少时间.它使用值调用提供的缓动函数来确定属性应该设置的值.只要所有缓动函数都实现相同的签名,它们就可以轻松换出,核心动画引擎不必知道区别.(这可以很好地分离关注点).

When you start a tween/animation, the animation engine remembers the start and end values you want. Then each time it updates, its figures out of how much time has passed. It call the supplied easing function with the values to figure out the value the property should be set to. As long as all of the easing functions implement the same signature, they can be swapped out with ease, and the core animation engine doesn't have to know difference. (Which makes for an excellent separation of concerns).

您会注意到我避免了明确地谈论 xy 位置,因为缓动与位置 per 没有任何特别的关系自己.缓动函数仅定义开始值和结束值之间的转换.这些可以是 x 坐标、颜色或对象的透明度.

You'll notice that I've avoided talking about x and y positions explicitly, because easing doesn't have anything specifically to do with position per se. An easing function just defines a transition between a start and end values. Those could be x coordinates, or a color, or the transparency of an object.

事实上,理论上,您可以应用不同的缓动函数来对不同的属性进行插值.希望这有助于阐明基本思想.

And in fact, in theory, you could apply different easing function to interpolate for different properties. Hopefully this helps shed some light on the basic idea.

这里是一个非常很酷的例子(使用稍微不同的签名,但原理相同)玩弄以了解缓动与位置的关系.

And here is a really cool example (that uses a slightly different signature, but is the same principle) to play with to get the idea of how easing relates to position.

编辑

这里有一些 jsFiddle 我拼凑起来展示了 javascript 中的一些基本用法.请注意,top 属性使用反弹补间,left 属性使用四边形补间.使用滑块模拟渲染循环.

Here is a little jsFiddle I threw together to demonstrate some of the basic usages in javascript. Notice that the top property is tweened using bounce, and the left property is tweened using a quad. Use the slider to simulate the render loop.

由于 easing 对象中的所有函数都具有相同的签名,您可以将它们中的任何一个相互交换.现在大多数这些东西都是硬编码的(比如开始和结束值、使用的补间函数和动画的长度),但是在动画助手的真实示例中,您可能希望通过在以下属性中:

Since all the functions in the easing object have the same signature, you can swap any of them out for each other. Right now most of these things are all hard-coded (things like start and end values, the tween functions that are used and the length of the animation), but in a real-world example of a animation helper, you would want to pass in the following properties:

  • 要更改的属性
  • 起始值(或者如果未定义undefined,则使用其当前值)
  • 最终价值
  • 动画的长度
  • 对您要使用的补间函数的引用.

动画引擎会在动画持续时间内跟踪这些设置,并且在每个更新周期内,它会使用补间参数来计算属性的新值.

The animation engine would keep track of these settings for the duration of the animation and during every update cycle, it would use the tweening argument to calculate the properties new value.

这篇关于什么是缓动函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆