Вопрос

Что подразумевается под ослаблением функции в контексте анимации. Похоже, что додзё, jquery, silverlight, flex и другие системы пользовательского интерфейса имеют представление о функции смягчения. Я не мог найти хорошее объяснение функций смягчения? Может ли кто -нибудь объяснить концепцию функций смягчения или указать на них хорошее объяснение, я заинтересован в концепции не в конкретных деталях структуры?

Строительное использование строго используется для местоположения или оно общее и может быть применено к какому -либо свойству объекта?

Это было полезно?

Решение

Функция смягчения, как правило, является функцией, которая описывает значение имущества с учетом процента полноты. Различные рамки используют немного разные вариации, но концепция легко понять, как только вы получите эту идею, но, вероятно, лучше всего посмотреть несколько примеров.

Сначала давайте посмотрим на интерфейс, который будут соблюдать все наши функции смягчения.

Наши функции смягчения займут несколько аргументов:

  • Процент.0.0 к 1.0).
  • ElaSpedtime: количество миллисекундов, которое анимация работает
  • StartValue: значение для начала (или значение, когда процент завершен 0%)
  • Endvalue: значение для окончания (или значение, когда процент завершен составляет 100%)
  • TotalDuration: общая желаемая длина анимации в миллисекундах

И вернет число, которое представляет значение, на которое должно быть установлено свойство.

Примечание. Это та же самая подпись, которую 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, что составляет четверть фактического расстояния между start а также end Значения, которые мы указали.

Если бы мы собирались на график этой функции, это выглядело бы примерно так:

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

Эта функция начнется медленно и заканчивается медленно, достигая максимальной скорости в середине.

Существует множество смягчающих/интерполяций, которые вы можете использовать: линейный, квадрадический, кубический, кварта, квинт, синус. И есть специальные функции смягчения, такие как Bounce и Elastic, которые имеют свои собственные.

Например, эластичная легкость в:

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

Возможно, кто -то другой может объяснить фактическую математическую часть, стоящую за интерполяцией, потому что, честно говоря, я не математический волшебник. Но это основной принцип смягчающих функций сами.

Когда вы запускаете подростку/анимацию, механизм анимации вспоминает желаемые значения начала и конечного. Затем каждый раз, когда он обновляется, его фигуры из того, сколько времени прошло. Он вызывает предоставленную функцию смягчения со значениями, чтобы выяснить значение, на которое должно быть установлено свойство. Пока все функции смягчения реализуют одну и ту же подпись, их можно легко поменяться, а двигатель основной анимации не должен знать разницу. (Что делает для превосходного разделения проблем).

Вы заметите, что я избегал говорить о x а также y позиции явно, потому что смягчение не имеет никакого конкретного связанного с позицией как таковой. Анкет Функция смягчения просто определяет переход между начальными и конечными значениями. Это могут быть x координаты, или цвет, или прозрачность объекта.

И на самом деле, теоретически, вы можете применить различную функцию смягчения для интерполяции для различных свойств. Надеемся, что это поможет пролить свет на основную идею.

И вот действительно Классный пример (Это использует немного другую подпись, но это тот же принцип), чтобы играть, чтобы понять, как смягчение относится к позиции.


Редактировать

Вот немного jsfiddle Я собрал вместе, чтобы продемонстрировать некоторые основные использование в JavaScript. Обратите внимание, что top Собственность насыщено с помощью отскока, и left Собственность подтягивается с использованием квадрата. Используйте ползунок, чтобы имитировать петлю рендеринга.

Поскольку все функции в 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: Всего времени анимации займет

time а также duration непосредственно связаны. Если у вас есть 2 -секундная анимация, вы увеличиваете time и передайте его функции смягчения linear. Анкет Функция вернет позицию, которая указывает на то, что ящик должен быть в этой позиции в данный момент времени.

Допустим, я двигаю коробку с 0 на 100 за 2 секунды. Если я хочу получить позицию коробки, скажем, на 700 миллисекунд, я бы позвонил linear функционируйте следующим образом:

linear(0.7, 0, 100, 2);

который вернется 35. Анкет 700 миллисекунд после начала анимации, позиция коробки будет на 35px. Посмотрим на это в действии.

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>


Парт, который требует внимания в этом коде:

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


И, наконец, пример extinoutquad.

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