Cubic Bezier

Кривые Безье третьего порядка (cubic bezier) являются основой для создания плавных анимаций в Popmotion. Они задаются четырьмя точками: начальной, конечной и двумя управляющими, определяющими форму кривой. В контексте анимации используются нормализованные координаты, где:

  • начальная точка всегда (0, 0)
  • конечная точка всегда (1, 1)
  • две промежуточные точки (x1, y1) и (x2, y2) задают характер ускорения и замедления

Функция cubic bezier интерполирует значение от 0 до 1 по времени, создавая нелинейное изменение скорости.


Математическая модель

Кривая описывается параметрическим уравнением:

B(t) = (1 - t)^3 * P0 +
       3(1 - t)^2 * t * P1 +
       3(1 - t) * t^2 * P2 +
       t^3 * P3

где:

  • t — параметр времени от 0 до 1
  • P0 = (0, 0)
  • P1 = (x1, y1)
  • P2 = (x2, y2)
  • P3 = (1, 1)

В анимации важен не сам путь, а зависимость y от x, которая задаёт easing-функцию.


Cubic Bezier в Popmotion

Popmotion предоставляет встроенный инструмент для работы с cubic bezier через модуль easing.

Пример создания кастомной функции:

import { cubicBezier } from "popmotion";

const ease = cubicBezier(0.42, 0, 0.58, 1);

Здесь:

  • 0.42, 0 — первая управляющая точка
  • 0.58, 1 — вторая управляющая точка

Эти значения соответствуют стандартной функции ease-in-out.


Использование в анимациях

Cubic bezier применяется в свойствах ease:

import { animate } from "popmotion";

animate({
  from: 0,
  to: 100,
  ease: cubicBezier(0.17, 0.67, 0.83, 0.67),
  onUpdate: value => {
    console.log(value);
  }
});

Функция ease преобразует линейное время в нелинейное, изменяя скорость анимации.


Интерпретация управляющих точек

Координаты (x1, y1) и (x2, y2) влияют на:

Горизонтальные значения (x):

  • определяют момент времени, когда начинается ускорение/замедление

Вертикальные значения (y):

  • определяют величину прогресса в этот момент времени

Типовые кривые

Линейная анимация

cubicBezier(0, 0, 1, 1)
  • равномерная скорость
  • отсутствует ускорение

Ease-in (ускорение в начале)

cubicBezier(0.42, 0, 1, 1)
  • медленный старт
  • быстрый разгон

Ease-out (замедление в конце)

cubicBezier(0, 0, 0.58, 1)
  • быстрый старт
  • плавная остановка

Ease-in-out

cubicBezier(0.42, 0, 0.58, 1)
  • плавное начало и завершение
  • наиболее естественное движение

Визуальное поведение кривой

Форма кривой определяет характер движения:

  • S-образная кривая — плавное ускорение и замедление
  • вогнутая вверх — быстрое начало
  • вогнутая вниз — медленный старт
  • резкие изгибы — агрессивные изменения скорости

Ограничения и особенности

  • значения x1 и x2 должны находиться в диапазоне [0, 1], иначе функция может стать некорректной
  • значения y могут выходить за пределы [0, 1], создавая эффекты overshoot (перелёт)
  • функция не обязана быть монотонной при экстремальных значениях

Пример overshoot-анимации

const ease = cubicBezier(0.34, 1.56, 0.64, 1);
  • значение временно превышает 1
  • создаётся эффект “пружины”

Комбинирование с другими функциями Popmotion

Cubic bezier может использоваться совместно с:

  • keyframes
  • timeline
  • spring (для более сложной физики)

Пример:

import { keyframes, cubicBezier } from "popmotion";

keyframes({
  values: [0, 100, 50, 150],
  ease: [
    cubicBezier(0.42, 0, 1, 1),
    cubicBezier(0, 0, 0.58, 1),
    cubicBezier(0.17, 0.67, 0.83, 0.67)
  ],
  duration: 2000
}).start(v => console.log(v));

Преобразование CSS easing в Popmotion

CSS-функции легко переносятся:

transition: all 0.3s cubic-bezier(0.25, 0.1, 0.25, 1);

Эквивалент:

cubicBezier(0.25, 0.1, 0.25, 1)

Практика настройки

Подбор параметров часто выполняется экспериментально:

  • уменьшение x1 → более резкий старт
  • увеличение y1 → ускорение в начале
  • уменьшение y2 → замедление перед концом
  • увеличение x2 → более позднее торможение

Инструменты для подбора кривых

Для точной настройки используются визуальные редакторы cubic bezier:

  • графическое перемещение контрольных точек
  • мгновенное отображение графика скорости
  • экспорт параметров

Производительность

Cubic bezier:

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

Однако:

  • не учитывает массу, силу, инерцию
  • уступает spring в реалистичности

Сравнение с spring-анимацией

Характеристика Cubic Bezier Spring
Контроль Точный Физический
Реалистичность Средняя Высокая
Производительность Высокая Средняя
Простота настройки Простая Сложнее

Использование в интерфейсах

Cubic bezier применяется для:

  • hover-эффектов
  • переходов между состояниями
  • появления/исчезновения элементов
  • микровзаимодействий

Поведенческие паттерны

Быстрые интерфейсы:

cubicBezier(0.4, 0, 0.2, 1)

Дружелюбные интерфейсы:

cubicBezier(0.25, 0.1, 0.25, 1)

Динамичные эффекты:

cubicBezier(0.68, -0.55, 0.27, 1.55)

Внутренний механизм Popmotion

Popmotion:

  1. принимает время t
  2. находит соответствующее значение x
  3. решает уравнение для нахождения t по x
  4. вычисляет y
  5. возвращает преобразованное значение

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


Ошибки при использовании

  • слишком резкие кривые → неестественная анимация
  • одинаковые easing для всех элементов → потеря выразительности
  • игнорирование длительности → кривая не раскрывается

Подход к проектированию анимации

  • сначала выбирается длительность
  • затем форма easing
  • затем тестируется в контексте интерфейса
  • корректируется по ощущениям

Расширенные сценарии

Cubic bezier может использоваться как часть сложных систем:

  • последовательные анимации с разными easing
  • синхронизация нескольких элементов
  • адаптивные анимации в зависимости от действий пользователя

Пример сложной анимации

import { timeline, cubicBezier } from "popmotion";

timeline([
  {
    track: "x",
    from: 0,
    to: 100,
    duration: 500,
    ease: cubicBezier(0.42, 0, 0.58, 1)
  },
  {
    track: "x",
    to: 200,
    duration: 300,
    ease: cubicBezier(0.17, 0.67, 0.83, 0.67)
  }
]).start({
  update: ({ x }) => console.log(x)
});

Итоговые свойства cubic bezier

  • детерминированность
  • высокая производительность
  • гибкость настройки
  • широкая совместимость (CSS, JS, Popmotion)

Использование cubic bezier остаётся фундаментальным инструментом при построении анимаций с контролируемым и предсказуемым поведением.