在动画的背景下,宽松功能的含义。似乎Dojo,jQuery,Silverlight,Flex和其他UI系统具有放松功能的概念。我无法找到对宽松功能的很好的解释?谁能解释放松功能的概念,或者对它们的很好的解释,我对框架的具体细节不感兴趣?

放宽是严格用于位置的,还是将其应用于对象的任何属性?

有帮助吗?

解决方案

宽松功能通常是描述给定完整性百分比的属性值的函数。不同的框架使用略有不同的变化,但是一旦您得到这个想法,该概念就很容易掌握,但是最好看一些示例。

首先,让我们查看我们所有宽松功能都会遵守的接口。

我们的轻松职能将有几个论点:

  • PERSTERCOMPLETE :(0.01.0).
  • Elaspedtime:动画一直在运行的毫秒数
  • StartValue:开始时的值(或完成百分比为0%时的值)
  • 端价:终止的值(或完成百分比为100%时的值)
  • 全杜:动画的总长度以毫秒为单位

并将返回代表应设置属性值的数字。

注意:这与JQuery用于其宽松功能相同的签名,我将借用示例。

最简单的理解是线性易于:

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

现在要使用它:

假设我们有一个动画,将要进行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

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

Linear ease

让我们看一下更复杂的宽松功能,在以下方面的二次便利。

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

并使用与以前相同的输入来查看相同的结果:

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 我们已指定的值。

如果我们要绘制此功能,它将看起来像这样:

Quad-Ease-In

现在让我们看一下基本的简化:

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

从本质上讲,这实质上是一种轻松的“相反”加速度曲线。它开始快速开始,然后减速至其最终值:

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

EaseInOut

此功能将开始缓慢和速度缓慢,在中间达到其最大速度。

您可以使用大量的轻松/插值:线性,四倍,立方,夸脱,Quint,正弦。并且有弹跳和弹性的特殊宽松功能,它们具有自己的宽松功能。

例如,弹性轻松在:

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

Elastic ease in

也许其他人可以解释插值背后的实际数学部分,因为老实说,我不是数学对象。但这是宽松功能本身的基本原理。

当您启动补间/动画时,动画引擎会记住所需的开始和最终值。然后,每次更新时,它都会从多少时间过去了。它调用带有值的宽松功能,以找出应设置属性的值。只要所有宽松功能都实现相同的签名,它们就可以轻松地交换,并且核心动画引擎不必知道差异。 (这使人们非常分开)。

您会注意到我避免谈论 xy 明确的职位,因为放宽没有任何专门与位置有关的 本身. 。宽松函数仅定义了开始值和终点之间的过渡。这些可能是 x 坐标或颜色或对象的透明度。

实际上,从理论上讲,您可以应用不同的轻松函数来插值不同的性质。希望这有助于对基本思想有所了解。

这是一个真的 很酷的例子 (使用略有不同的签名,但是相同的原则),可以扮演宽松与位置之间的关系的想法。


编辑

这有点 JSFIDDLE 我一起投掷以演示JavaScript中的一些基本用法。注意 top 使用弹跳对财产进行补间,然后 left 使用Quad对属性进行了补间。使用滑块模拟渲染循环。

由于所有功能 easing 对象具有相同的签名,您可以将它们互相交换。目前,这些内容大多数都是硬编码的(诸如开始和结束值,使用的补间函数以及动画的长度),但是在动画助手的真实示例中,您需要通过在以下属性中:

  • 要更改的属性
  • 起始值(如果离开 undefined 然后使用其当前值)
  • 最终值
  • 动画应该是
  • 对您要使用的补间功能的引用。

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

其他提示

宽松功能是一种控制动画速度以产生预期效果(弹跳,放大和缓慢等)的算法。

看看什么 MSDN必须对他们说 有关更多细节。

我想向这个旧问题发布答案,即使它有一个公认的答案。 32bitkid 做出了必要的解释。我要添加的是基本的实际实现,因为我找不到一个(我也发布了一个 问题 关于它)。

以这个简单的线性动画为例。我怀疑这需要任何解释,因为该代码是自称的。我们计算一个恒定的增量值,该值不会随着时间而变化,在每次迭代中,我们都会增加框的位置。我们将直接修改位置变量,然后将其应用于框。

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>


现在,让我们添加放松。我们通过使用简单 linear (不开除)。这将导致上述相同的动画,但是方法是不同的。这次,我们不会直接修改位置变量。我们要修改的是时间。

function linear(time, begin, change, duration) {
    return change * (time / duration) + start;
}

首先,让我们谈谈参数。

  • time: :经过的时间
  • begin: :属性的初始值(宽度,左,边距,不透明度等)
  • change: :位移,(最终值 - 启动值)
  • duration: :动画将花费的总时间

timeduration 直接相关。如果您有2秒的动画,您会增加 time 并将其传递给宽松功能 linear. 。该功能将返回一个位置,该位置表明该框应在给定时间处于该位置。

假设我在2秒内将一个盒子从0移至100。如果我想获得盒子的位置,请在700毫秒处说 linear 以以下方式函数:

linear(0.7, 0, 100, 2);

会返回 35. 。动画启动后700毫秒,Box的位置为35%。让我们看看这一点。

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 timeIncrement = duration / iterations;
var position      = 0;
var time          = 0;

function move() {
	time += timeIncrement;
	position = linear(time, startPosition, distance, duration);
	if (position >= endPosition) {
		clearInterval(handler);
		box.style.left = endPosition + "px";
		return;
	}
	box.style.left = position + "px";
}

var handler = setInterval(move, 1000/fps);

function linear(time, begin, change, duration) {
	return change * (time / duration) + begin;
}
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>


在此代码中需要注意的PARTH是:

var timeIncrement = duration / iterations;
var time = 0;

function move() {
    time += timeIncrement;
    position = linear(time, startPosition, distance, duration);
    // ...

在第一个动画中,我们直接修改了位置变量。我们需要一个恒定的位置增量值。我们计算的方式是 posIncrement = distance / iterations. 。通过放松,我们不再修改位置变量,而是时间变量。因此,我们需要时间增量值。我们以相同的方式进行计算,只有这次我们分割 duration 经过 iterations. 。我们随时间增加的时间增加了时间,并将时间传递到宽松功能,而宽松功能返回了我们的下一个位置该盒子应占据。

total distance / iterations (frames) = position change per frame
total duration / iterations (frames) = time change per frame

这是眼睛的一些图。

Ease function graph


最后,一个简单的示例。

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 timeIncrement = duration / iterations;
var time          = 0;
var position      = 0;

function move() {
  time += timeIncrement;
  position = easeInOutQuad(time, startPosition, distance, duration);
  if (position >= endPosition) {
    clearInterval(handler);
    box.style.left = endPosition + "px";
    return;
  }
  box.style.left = position + "px";
}

var handler = setInterval(move, 1000 / fps);

function easeInOutQuad(t, b, c, d) {
  if ((t /= d / 2) < 1) {
    return c / 2 * t * t + b;
  } else {
    return -c / 2 * ((--t) * (t - 2) - 1) + b;
  }
}
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提供的宽松功能。

http://jqueryui.com/demos/effect/easing.html

在现实生活中认为不像计算机那样工作。认为不要像您无法假装女友会立即爱上您一样从开始到关闭。因此,科学家和计算机人员(对您的女友一无所知),发明了轻松的功能。就像是要应用或切换动画之类的东西,而不是立即使用。因此,如果您将矩形从左侧移动到右侧,它不会像机器人一样移动:“启动,以恒定的速度移动并立即停止移动”,但是“启动,不断增长速度,不断降低速度并最终停止”。因此,放松就像让一些动画,功能,物体或东西一样,在现实生活中表现得像事物一样。每一个轻松效应都定义了行为,这就是为什么我们具有“弹性”,“弹跳”轻松效果等。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top