onUpdate — один из ключевых колбэков в библиотеке
mo.js, обеспечивающий доступ к состоянию анимации на
каждом кадре её воспроизведения. Используется для синхронизации
пользовательской логики с прогрессом анимации, позволяя динамически
изменять свойства DOM-элементов, вычислять значения в реальном времени и
интегрировать анимацию с внешними системами.
Колбэк вызывается при каждом обновлении кадра (frame tick), что делает его важным инструментом для создания сложных и реактивных визуальных эффектов.
onUpdate(progress)
Параметры:
progress — число в диапазоне от 0 до
1, отражающее текущий прогресс анимации:
0 — начало анимации1 — завершениеЗначение интерполируется во времени с учётом easing-функции, заданной для конкретной анимации.
const tween = new mojs.Tween({
duration: 1000,
onUpdate: (progress) => {
console.log(progress);
}
});
tween.play();
В этом примере при каждом кадре выводится текущее значение прогресса.
onUpdate вызывается в рамках внутреннего цикла
рендеринга mo.js, который основан на requestAnimationFrame.
Это означает:
progress остаются корректными независимо от
FPSonUpdateОдно из основных применений — ручное управление стилями:
const el = document.querySelector('.box');
const tween = new mojs.Tween({
duration: 1000,
onUpdate: (p) => {
const x = 200 * p;
el.style.transform = `translateX(${x}px)`;
}
});
Здесь реализовано линейное перемещение элемента по оси X.
onUpdate часто используется вместе с пользовательской
интерполяцией:
const lerp = (start, end, t) => start + (end - start) * t;
const tween = new mojs.Tween({
duration: 1000,
onUpdate: (p) => {
const scale = lerp(1, 2, p);
el.style.transform = `scale(${scale})`;
}
});
Это даёт полный контроль над изменением параметров, независимо от встроенных механизмов mo.js.
onUpdateХотя mo.js автоматически применяет easing к анимациям, внутри
onUpdate можно вручную учитывать или игнорировать его:
const easing = mojs.easing.ease.out;
const tween = new mojs.Tween({
duration: 1000,
onUpdate: (p) => {
const eased = easing(p);
el.style.opacity = eased;
}
});
Таким образом достигается дополнительная гибкость в управлении поведением.
onUpdate позволяет синхронизировать несколько
элементов:
const el1 = document.querySelector('.a');
const el2 = document.querySelector('.b');
const tween = new mojs.Tween({
duration: 1000,
onUpdate: (p) => {
el1.style.transform = `translateX(${100 * p}px)`;
el2.style.transform = `translateY(${100 * p}px)`;
}
});
Один tween управляет сразу несколькими анимациями.
Внутри onUpdate можно использовать замыкания для доступа
к внешним переменным:
let counter = 0;
const tween = new mojs.Tween({
duration: 1000,
onUpdate: (p) => {
if (p > 0.5 && counter === 0) {
console.log('Половина анимации');
counter++;
}
}
});
Это позволяет отслеживать события внутри анимации.
В составе Timeline:
const timeline = new mojs.Timeline();
const tween = new mojs.Tween({
duration: 1000,
onUpdate: (p) => {
console.log('Timeline progress:', p);
}
});
timeline.add(tween);
timeline.play();
Каждый tween внутри таймлайна сохраняет собственный
onUpdate.
Частый вызов onUpdate требует аккуратного подхода:
Рекомендации:
transform и opacity вместо
свойств, вызывающих reflowПлохо:
onUpdate: (p) => {
el.style.left = (100 * p) + 'px'; // вызывает layout
}
Лучше:
onUpdate: (p) => {
el.style.transform = `translateX(${100 * p}px)`;
}
onUpdate подходит для работы с canvas:
const ctx = canvas.getContext('2d');
const tween = new mojs.Tween({
duration: 1000,
onUpdate: (p) => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(0, 0, 100 * p, 50);
}
});
Позволяет управлять рендерингом без ограничений DOM.
Можно реализовать собственную физику:
const tween = new mojs.Tween({
duration: 1000,
onUpdate: (p) => {
const gravity = 9.8;
const t = p * 1; // время
const y = 0.5 * gravity * t * t;
el.style.transform = `translateY(${y}px)`;
}
});
Такой подход позволяет выходить за рамки стандартных easing-функций.
onUpdate может использоваться для:
onUpdate: (p) => {
progressBar.style.width = `${p * 100}%`;
}
onStart
и onComplete| Колбэк | Когда вызывается |
|---|---|
onStart |
один раз при запуске |
onUpdate |
на каждом кадре |
onComplete |
один раз при завершении |
onUpdate — единственный, который обеспечивает
непрерывный контроль.
1. Перегрузка логикой
onUpdate: (p) => {
heavyCalculation(); // плохо
}
2. Создание функций внутри
onUpdate: (p) => {
const f = () => {}; // лишнее
}
3. Частое обращение к DOM
onUpdate: (p) => {
document.querySelector('.box') // дорого
}
Реактивная анимация:
onUpdate: (p) => {
state.value = p;
}
Связка с внешними библиотеками:
onUpdate: (p) => {
threeObject.rotation.y = p * Math.PI * 2;
}
onUpdate часто используется вместе с декларативной
анимацией mo.js:
const shape = new mojs.Shape({
x: { 0: 200 },
duration: 1000,
onUpdate: (p) => {
console.log('Дополнительная логика', p);
}
});
Встроенная анимация управляет свойствами, а onUpdate
добавляет дополнительное поведение.
onUpdate может влиять на сам tween:
onUpdate: function(p) {
if (p > 0.8) {
this.pause();
}
}
Позволяет динамически управлять жизненным циклом анимации.
onUpdate — это низкоуровневый механизм контроля
анимации, предоставляющий полный доступ к её прогрессу. Он превращает
mo.js из декларативного инструмента в гибкую платформу для построения
сложных интерактивных систем, где каждая миллисекунда анимации может
быть обработана и использована в пользовательской логике.