Передача данных в коллбэки

В Motion One коллбэки анимации устроены таким образом, что основной поток данных поступает через параметры latest и объект info, однако архитектура библиотеки допускает передачу произвольного контекста через замыкания и пользовательские структуры данных, связываемые с жизненным циклом анимации.

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

Типовая сигнатура:

onUpdate: (latest, info) => {}
onComplete: (latest, info) => {}
onStart: (latest, info) => {}

latest отражает текущее значение анимируемого свойства. info содержит метаданные выполнения анимации:

  • time — текущее время анимации
  • elapsed — прошедшее время
  • progress — прогресс от 0 до 1
  • speed — скорость воспроизведения
  • delta — изменение за кадр
  • repeat — номер повторения
  • direction — направление проигрывания

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

Передача данных через замыкания

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

const factor = 1.5;
const baseValue = 100;

animate(0, baseValue, {
  onUpdate: (latest, info) => {
    const computed = latest * factor;
    const result = computed + baseValue;
  }
});

Переменные factor и baseValue не входят в API Motion One, но остаются доступными через лексическое окружение функции.

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

Фабричные функции для генерации коллбэков

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

const createUpdateHandler = (scale, offset) => {
  return (latest, info) => {
    const value = (latest + offset) * scale;
  };
};

animate(0, 1, {
  onUpdate: createUpdateHandler(2, 10)
});

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

Связывание данных с DOM-элементами

При работе с DOM-элементами часто требуется ассоциировать анимацию с метаданными конкретного узла. Это реализуется через dataset или пользовательские поля объекта.

const element = document.querySelector(".box");
element._meta = {
  id: 42,
  multiplier: 3
};

animate(0, 100, {
  onUpdate: (latest, info) => {
    const { multiplier } = element._meta;
    const transformed = latest * multiplier;
  }
});

Данные хранятся вне анимационного движка и доступны через замыкание на DOM-узел.

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

При массовом создании анимаций применяется паттерн фабрики, где создаётся функция, принимающая контекст и возвращающая конфигурацию Motion One.

const createAnimation = (context) => {
  return animate(0, 1, {
    duration: context.duration,
    onUpdate: (latest, info) => {
      const value = latest * context.scale;
      context.onProgress?.(value, info);
    }
  });
};

Контекст выступает единым источником данных, управляющим поведением анимации.

Использование общего состояния между коллбэками

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

const state = {
  max: 0,
  sum: 0
};

animate(0, 100, {
  onUpdate: (latest) => {
    state.sum += latest;
    if (latest > state.max) state.max = latest;
  },
  onComplete: () => {
    state.finished = true;
  }
});

Общий объект состояния позволяет аккумулировать данные между различными фазами анимации.

Передача параметров через обёртки коллбэков

Иногда требуется динамическая параметризация поведения без создания фабрики. В этом случае применяется обёртка функции.

const withConfig = (handler, config) => {
  return (latest, info) => {
    handler(latest, info, config);
  };
};

const handler = (latest, info, config) => {
  const value = latest * config.factor;
};

animate(0, 1, {
  onUpdate: withConfig(handler, { factor: 4 })
});

Такой слой абстракции отделяет логику обработки от параметров конфигурации.

Контекст временной шкалы и группировка данных

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

const timelineState = {
  phase: 0,
  values: []
};

const step = animate(0, 1, {
  onUpdate: (latest) => {
    timelineState.values.push(latest);
  },
  onComplete: () => {
    timelineState.phase += 1;
  }
});

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

Ограничения и особенности модели передачи данных

Архитектура Motion One не предусматривает отдельного канала пользовательских данных внутри коллбэков. Это приводит к следующим характерным особенностям:

  • отсутствие встроенного context объекта в сигнатуре
  • невозможность передачи произвольных аргументов через animate
  • зависимость от внешнего состояния и замыканий
  • необходимость явного управления жизненным циклом данных

Такая модель делает поведение предсказуемым, но переносит ответственность за структуру данных на уровень прикладного кода.

Композиция коллбэков с внешними данными

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

const logProgress = (latest, info) => {
  console.log(info.progress);
};

const computeMetric = (latest, info, metrics) => {
  metrics.push(latest * info.delta);
};

const metrics = [];

animate(0, 1, {
  onUpdate: (latest, info) => {
    logProgress(latest, info);
    computeMetric(latest, info, metrics);
  }
});

Разделение логики позволяет управлять различными потоками данных независимо друг от друга.