Что такое функция смягчения?

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

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

5 ответов


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

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

наши ослабляя функции примут несколько аргументов:

  • percentComplete: (0.0 to 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

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

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

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

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

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

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 позиции явно, потому что ослабление не имеет ничего общего с позицией per se. Функцию плавности просто определяет переход между начальным и конечным значениями. Это может быть x координаты, или цвет, или прозрачность объекта.

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

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


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

вот немного jsFiddle я собрал вместе, чтобы продемонстрировать некоторые из основных обычаев в javascript. Обратите внимание, что top свойство tweened с помощью bounce, и left свойство tweened с помощью quad. Используйте ползунок для имитации цикл визуализации.

так как все функции в easing объект имеет одинаковую подпись, вы можете поменять любой из них друг для друга. Сейчас большинство из этих вещей жестко закодированы (например, начальные и конечные значения, используемые функции tween и длина анимации), но в реальном примере помощника анимации вы хотели бы передать следующие свойства:

  • свойство, которое необходимо изменить
  • начальное значение (или если оставить undefined затем используйте его текущее значение)
  • конечное значение
  • длина анимации должна быть
  • ссылка на функцию tweening, которую вы хотите использовать.

анимационный движок будет отслеживать эти параметры в течение всей анимации и во время каждого цикла обновления он будет использовать аргумент 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 (без смягчения). Это приведет к той же анимации выше, но подход отличается. На этот раз мы не будем изменять переменную position напрямую. Что мы будем изменять время.

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

во-первых, давайте поговорим о параметрах.

  • time: затраченное время
  • begin: начальное значение свойства (ширина, левая сторона, поле, непрозрачность и т. д.)
  • change: водоизмещение, (конечное значение - начальное значение)
  • duration: общее время анимации будет забрать

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

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


Это свойство (размер, форма, местоположение) переход из одного состояния в другое.

вот некоторые аккуратные маленькие графики, описывающие функции смягчения, предлагаемые jQuery ui.

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


думает, что в реальной жизни не работают как компьютеры. Думает, что не переключаться с ВКЛ и выкл сразу же, как вы не можете притвориться, что ваша подруга будет любить вас сразу. Поэтому ученые и компьютерные люди (которые ничего не знают о вашей подруге), изобрели облегчающие функции. Это так же, как применять или переключать такие вещи, как анимация, не сразу. Поэтому, если вы перемещаете прямоугольник слева направо, он не движется как робот: "начните, двигайтесь с помощью постоянная скорость и остановка немедленно", но "начать, увеличить скорость постоянно, уменьшить скорость постоянно и остановить, наконец". Поэтому ослабление - это то же самое, что позволить некоторым анимациям, функциям, объектам или вещам вести себя как вещи в реальной жизни. Каждый эффект легкости определяет поведение, поэтому у нас есть "эластичные", "подпрыгивающие" эффекты легкости и так далее.