В Motion One коллбэки анимации устроены таким образом, что основной
поток данных поступает через параметры latest и объект
info, однако архитектура библиотеки допускает передачу
произвольного контекста через замыкания и пользовательские структуры
данных, связываемые с жизненным циклом анимации.
Коллбэки в Motion One принимают предсказуемый набор аргументов, где ключевую роль играет текущая анимационная величина и служебная информация о состоянии проигрывания.
Типовая сигнатура:
onUpdate: (latest, info) => {}
onComplete: (latest, info) => {}
onStart: (latest, info) => {}
latest отражает текущее значение анимируемого свойства.
info содержит метаданные выполнения анимации:
time — текущее время анимацииelapsed — прошедшее времяprogress — прогресс от 0 до 1speed — скорость воспроизведения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-элементами часто требуется ассоциировать анимацию с
метаданными конкретного узла. Это реализуется через 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);
}
});
Разделение логики позволяет управлять различными потоками данных независимо друг от друга.