Spring анимации

Spring-анимации в Motion One реализуют физически-ориентированную модель движения, в которой переход значения определяется не фиксированной временной кривой, а поведением упругой системы. Вместо привычных easing-функций используется приближение к целевому состоянию через дифференциальное уравнение демпфированного осциллятора. Такой подход позволяет получать естественные движения с инерцией, переразгоном и плавным затуханием.


Физическая модель пружины

Spring-модель базируется на классическом уравнении:

  • сила пропорциональна смещению от цели
  • присутствует демпфирование, уменьшающее колебания
  • система стремится к состоянию равновесия

Поведение описывается параметрами:

  • stiffness — жёсткость пружины
  • damping — коэффициент демпфирования
  • mass — масса объекта
  • velocity — начальная скорость

Упрощённая интерпретация:

  • высокая жёсткость ускоряет движение к цели
  • высокое демпфирование подавляет колебания
  • низкое демпфирование создаёт эффект “пружинящего” overshoot

Базовая конфигурация spring

Spring задаётся как easing-функция внутри параметров анимации:

import { animate, spring } from "motion";

animate(
  ".box",
  { x: 300 },
  {
    easing: spring({
      stiffness: 120,
      damping: 20,
      mass: 1
    })
  }
);

Каждый параметр влияет на динамику:

stiffness

Определяет скорость притяжения к цели.

  • низкое значение → медленное, мягкое движение
  • высокое значение → быстрое, резкое приближение

damping

Определяет затухание колебаний.

  • низкое → выраженный “bounce”
  • высокое → почти без колебаний

mass

Влияет на инерцию.

  • высокая масса → более тяжёлое, инертное движение
  • низкая масса → отзывчивое поведение

Типы поведения spring-системы

Spring-движение делится на несколько режимов:

Недемпфированная система

Характеризуется постоянными колебаниями без стабилизации. В UI используется редко.

Слабо демпфированная система

Создаёт выраженный overshoot и эффект “пружины”. Часто используется для интерактивных интерфейсов.

Критическое демпфирование

Система достигает цели максимально быстро без колебаний. Оптимально для UI-переходов.

Пере-демпфированная система

Медленное достижение цели без возвратных движений. Используется для тяжёлых, “плавных” эффектов.


Начальная скорость и инерция

Параметр velocity позволяет учитывать текущее движение элемента:

animate(
  ".box",
  { x: 500 },
  {
    easing: spring({
      stiffness: 200,
      damping: 25,
      velocity: 800
    })
  }
);

Скорость усиливает реализм при:

  • перетаскивании элементов
  • завершении drag-жестов
  • переходах после scroll-интеракций

Spring в интерактивных сценариях

Spring-модель особенно эффективно проявляется в событиях пользовательского ввода.

Drag-анимации

import { draggable, animate, spring } from "motion";

draggable(".card", {
  onDragEnd(info) {
    animate(
      ".card",
      { x: 0, y: 0 },
      {
        easing: spring({
          stiffness: 180,
          damping: 22,
          velocity: info.velocity.x
        })
      }
    );
  }
});

Система возвращает элемент в исходное положение с сохранением импульса.


Hover-интеракции

animate(
  ".button",
  { scale: 1.05 },
  {
    easing: spring({
      stiffness: 300,
      damping: 15
    })
  }
);

Spring обеспечивает “живую” реакцию без линейного увеличения.


Интерполяция сложных трансформаций

Spring применяется не только к простым числам, но и к комплексным transform-значениям:

  • translate
  • scale
  • rotate
  • skew
animate(
  ".box",
  {
    x: 200,
    rotate: 45,
    scale: 1.2
  },
  {
    easing: spring({
      stiffness: 150,
      damping: 18
    })
  }
);

Каждое свойство интерполируется независимо, но синхронизировано по времени системы.


Сравнение spring и easing

Традиционные easing-функции:

  • основаны на времени
  • детерминированы
  • не учитывают инерцию

Spring-анимации:

  • основаны на физике
  • зависят от состояния системы
  • реагируют на скорость и сопротивление

Различие проявляется в поведении:

  • easing → предсказуемые кривые
  • spring → естественные “живые” движения

Настройка ощущения движения

Поведение spring-системы регулируется комбинацией параметров:

Быстрое и резкое движение

  • высокая stiffness
  • высокая damping
  • низкая mass

Мягкое и инерционное движение

  • средняя stiffness
  • низкая damping
  • высокая mass

Bounce-эффект

  • средняя stiffness
  • низкая damping
  • средняя mass

Множественные spring-анимации

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

animate(
  ".panel",
  {
    x: 400,
    opacity: 1,
    scale: 1
  },
  {
    easing: spring({
      stiffness: 140,
      damping: 20
    })
  }
);

Это предотвращает рассинхронизацию трансформаций.


Поведение при прерывании

Spring-система сохраняет физическое состояние при остановке анимации:

  • текущая скорость переносится в новую цель
  • позиция становится начальным состоянием новой траектории
  • движение не обнуляется, а продолжается
const controls = animate(".box", {
  x: 300
}, {
  easing: spring({ stiffness: 120, damping: 18 })
});

controls.stop();

animate(".box", {
  x: 600
}, {
  easing: spring({ stiffness: 120, damping: 18 })
});

Производительность spring-анимаций

Spring не требует заранее рассчитанных keyframes, что снижает нагрузку в ряде сценариев:

  • отсутствие предвычисленных кривых
  • вычисление следующего состояния на каждом кадре
  • стабильная работа при изменении цели во время анимации

Оптимизация достигается за счёт:

  • ограниченного числа итераций интеграции
  • адаптивного шага времени
  • прекращения вычислений при достижении порога покоя

Порог остановки движения

Система завершает анимацию при достижении двух условий:

  • скорость ниже порогового значения
  • расстояние до цели минимально

Это предотвращает бесконечные микроколебания.


Композиция spring с timeline

Spring может быть встроен в последовательности анимаций:

import { timeline, spring } from "motion";

timeline([
  [".box", { x: 200 }, { easing: spring({ stiffness: 150, damping: 20 }) }],
  [".box", { y: 100 }, { easing: spring({ stiffness: 120, damping: 18 }) }]
]);

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


Особенности восприятия spring-модели

Визуальное поведение spring определяется сочетанием факторов:

  • ускорение в начале движения
  • замедление при приближении к цели
  • возможный overshoot
  • возврат к состоянию равновесия

Такая динамика приближена к физическим объектам и снижает ощущение “цифровой” анимации в интерфейсах.