В ранних версиях mo.js основной моделью построения анимаций являлось
создание отдельных объектов с последующей немедленной инициализацией
через метод play() или автоматическим запуском при создании
экземпляра.
Ключевая особенность этого подхода — максимальная декларативность внутри одного конструктора:
const tween = new mojs.Tween({
duration: 1000,
delay: 0,
easing: 'linear.none',
onUpdate(progress) {
console.log(progress);
}
});
tween.play();
Устаревание данного стиля связано с тем, что:
Позднее этот стиль начал вытесняться системой Timeline,
где управление временем стало централизованным.
Tween в старом API использовался как универсальный
строительный блок. Он применялся не только для анимации числовых
значений, но и для управления логикой эффектов.
Типичный пример:
const tween = new mojs.Tween({
duration: 800,
onUpdate(p) {
element.style.transform = `scale(${p})`;
}
});
Проблема заключалась в том, что:
В современных подходах Tween разделён на более специализированные сущности: shape, burst, timeline.
Ранний Shape API представлял собой монолитную
конфигурацию, где геометрия, стиль и анимация находились в одном
объекте.
const shape = new mojs.Shape({
shape: 'circle',
radius: 50,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
duration: 600
});
shape.play();
Устаревшие особенности:
Позднее API было переработано: появилась концепция
Custom Shape, где геометрия отделена от анимационной
логики.
До внедрения унифицированной временной шкалы использовались разрозненные параметры:
delaydurationrepeatyoyoОднако их поведение различалось между Tween и Shape, что приводило к несогласованности.
Пример старого поведения:
new mojs.Shape({
duration: 500,
repeat: 3,
yoyo: true
});
Проблема заключалась в том, что:
repeat не синхронизировался внутри Timelineyoyo не поддерживал одинаковую интерполяцию easingПозднее введение Timeline нормализовало эти параметры.
Первоначальный Timeline был представлен как простой
контейнер:
const tl = new mojs.Timeline();
tl.add(tween1, tween2);
tl.play();
Недостатки:
Также отсутствовали методы:
Эти ограничения делали систему непригодной для сложных сцен.
Ранний формат easing представлял собой строковые идентификаторы:
easing: 'quad.out'
easing: 'elastic.out'
easing: 'bounce.in'
Проблема заключалась в:
Позднее easing стал объектной системой с унифицированной интерполяцией.
Ранее жизненный цикл анимации полностью строился вокруг callback-функций:
onStart()
onUpdate(progress)
onComplete()
Основные ограничения:
Типичная проблема:
onUpdate(p) {
if (p > 0.5) {
this.stop(); // небезопасное управление внутри цикла
}
}
Позднее появилась более структурированная событийная модель с внешним контролем.
Ранние версии Shape использовали фиксированные параметры трансформации:
scalerotatexynew mojs.Shape({
scale: { 0: 1 },
rotate: { 0: 180 }
});
Проблема заключалась в:
Современные версии заменили это более гибкой системой трансформаций на основе композиции.
Ранний Burst представлял собой фиксированную систему
разлета элементов:
new mojs.Burst({
radius: { 0: 100 },
count: 10
});
Ограничения:
Позднее Burst был переработан в систему частиц с расширенной моделью траекторий.
В ранней архитектуре многие эффекты напрямую зависели от DOM-элементов:
new mojs.Tween({
el: document.querySelector('.box'),
onUpdate(p) {
el.style.opacity = p;
}
});
Проблемы:
Позднее архитектура была частично абстрагирована для поддержки canvas-ориентированных рендеров.
До перехода к современным сборщикам использовался глобальный объект:
const mojs = window.mojs;
Минусы:
Современные версии поддерживают модульную структуру, но старый глобальный API остаётся в legacy-режиме.
Ранние версии имели неочевидные дефолтные параметры:
Это приводило к поведению, которое сложно было предсказать:
new mojs.Shape({
shape: 'circle'
});
Без явного duration объект мог мгновенно завершить анимацию.
До появления развитых Timeline композиция выглядела как цепочка независимых объектов:
tween1.play();
tween2.play();
tween3.play();
Проблемы:
Переход к декларативной композиции стал ключевым этапом развития библиотеки.
Ранние версии не имели оптимизаций:
Это приводило к деградации производительности при большом количестве анимаций:
for (let i = 0; i < 100; i++) {
new mojs.Shape({ radius: i }).play();
}
Современная архитектура использует централизованный цикл обновлений.