Подтвердить что ты не робот

Формула упрощения и облегчения анимации

Скажем, если я делаю Ease-Out, а затем Легкая анимация перемещения объекта из координаты X1 в координату X2 S шагов с равными интервалами времени. Может ли кто-нибудь предложить формулу для вычисления этих координат движения X?

4b9b3361

Ответ 1

Квадратичное облегчение где:

t = текущее время
б = начальное значение
с = изменение стоимости
д = продолжительность

 function (float time, float startValue, float change, float duration) {
     time /= duration / 2;
     if (time < 1)  {
          return change / 2 * time * time + startValue;
     }

     time--;
     return -change / 2 * (time * (time - 2) - 1) + startValue;
 };

источник: http://gizma.com/easing/

Ответ 2

На самом деле, я бы предпочел использовать функцию, которая получает время в [0; 1] и выведите время в [0; 1], так что мы можем применить результат к любому типу (2D-вектор, 3D-вектор,...).

Решение 1

Для квадратичного ослабления in/out кривая разделяется на две функции в зависимости от t:

  • когда t < 0,5: f(t) = square(t)
  • когда t >= 0,5: f(t) = 1 - square(t - 1) + 0.5

После редукции в C это даст следующее:

float InOutQuadBlend(float t)
{
    if(t <= 0.5f)
        return 2.0f * square(t);
    t -= 0.5f;
    return 2.0f * t * (1.0f - t) + 0.5;
}

Решение 2 (Безье)

Еще одна интересная кривая смешения - та, которую дает Безье, которая имеет преимущество, чтобы быть достаточно оптимизированной (нет, если). Вы можете проверить кривую на Wolfram. И вот код C:

float BezierBlend(float t)
{
    return square(t) * (3.0f - 2.0f * t);
}

Решение 3 (параметрическая функция)

Edit:
Другой метод, предложенный @DannyYaroslavski, - это простая формула, предложенная здесь.

Он параметрический и получает хорошее ускорение и замедление в/в.

С альфа = 2 вы получаете эту функцию:

curve

Что переводит в C так:

float ParametricBlend(float t)
{
    float sqt = square(t);
    return sqt / (2.0f * (sqt - t) + 1.0f);
}

Ответ 3

У меня возникла та же проблема: я хотел анимировать свой график (Ease in-out).

Мозговой штурм дал мне два пути:

1) Тригонометрическая формула. Во-первых, я написал y=(sin(x/π*10-π/2)+1)/2, аналогом которого является sin^2((5*x)/π)

float TrygoEase (float x) {
    float y=(float)Math.pow(Math.sin(5*x/Math.PI),2);
    return y;
}

2) Две параболы. Это было не сложно. Я просто использовал y=2*x*x для [0;0.5] и y=-2(x-1)^2+1 для [0.5;1]

float ParabolEase(float x) {
    float y=2*x*x;
    if(x>0.5f){
        x-=1;
        y=-2*x*x+1;
    }
    return y;
} 

Используйте эти способы для x=[0;1], что также возвращает y=[0;1].

Теперь вы можете сравнить эти графики:

enter image description here

Ответ 4

Во всех вышеперечисленных решениях отсутствуют примеры использования.

Нашли хорошее решение здесь:

 function animate({timing, draw, duration}) {

  let start = performance.now();

  requestAnimationFrame(function animate(time) {
    // timeFraction goes from 0 to 1
    let timeFraction = (time - start) / duration;
    if (timeFraction > 1) timeFraction = 1;

    // calculate the current animation state
    let progress = timing(timeFraction)

    draw(progress); // draw it

    if (timeFraction < 1) {
      requestAnimationFrame(animate);
    }

  });
}

Пример использования:

animate({
  duration: 1000,
  timing(timeFraction) { // here you can put other functions
    return timeFraction;
  },
  draw(progress) {
    elem.style.width = progress * 100 + '%';
  }
});

Другая функция:

function quad(timeFraction) {
  return Math.pow(timeFraction, 2)
}

Подробнее здесь