Библиотека mo.js изначально ориентирована на декларативное описание анимаций, где состояние объектов определяется параметрами твинов, шейпов и таймлайнов. Управление состоянием в таком подходе строится не через классическую модель хранения данных, а через композицию анимационных сущностей и их параметров.
Ключевыми элементами, формирующими состояние, выступают:
Состояние не хранится централизованно — оно распределено между объектами и их параметрами.
Состояние объекта определяется набором его текущих параметров:
radius, scale,
angle)x, y)opacity)fill, stroke)duration,
delay)Каждое из этих свойств может:
Пример декларативного состояния:
const circle = new mojs.Shape({
shape: 'circle',
radius: { 0: 50 },
fill: 'transparent',
stroke: 'blue',
strokeWidth: { 10: 0 },
duration: 1000
});
Здесь состояние описано как переход от одного значения к другому.
mo.js использует иммутабельную модель описания анимаций:
Это означает:
Любое свойство может быть функцией:
const shape = new mojs.Shape({
x: () => Math.random() * 300,
y: () => Math.random() * 300,
scale: { 0: 1 }
});
Это позволяет:
Timeline объединяет несколько анимаций и управляет их синхронизацией.
const timeline = new mojs.Timeline();
timeline.add(circle, anotherShape);
timeline.play();
В этом контексте:
mo.js предоставляет API для управления состоянием через методы воспроизведения:
.play().pause().stop().replay().setProgress(progress)Пример:
circle.setProgress(0.5);
Это устанавливает состояние объекта на середину анимации.
Таким образом:
Состояние анимации может зависеть от:
Пример синхронизации со скроллом:
window.addEventListener('scroll', () => {
const progress = window.scrollY / 1000;
circle.setProgress(progress);
});
Это превращает анимацию в функцию от состояния интерфейса.
Хотя mo.js не имеет встроенного хранилища состояния, возможна интеграция с внешними решениями:
Пример:
store.subscribe(() => {
const state = store.getState();
circle.setProgress(state.animationProgress);
});
mo.js выступает как визуализатор состояния, а не его источник.
Каждый объект mo.js хранит собственное локальное состояние:
Это состояние:
Метод tune() позволяет динамически обновлять
параметры:
circle.tune({
fill: 'red',
radius: 100
});
Особенности:
Состояние анимации зависит не только от значений, но и от easing-функций:
const shape = new mojs.Shape({
scale: { 0: 1 },
easing: 'elastic.out'
});
Easing определяет:
Burst генерирует множество элементов с независимыми состояниями:
const burst = new mojs.Burst({
count: 10,
radius: { 0: 100 }
});
Каждый элемент:
Это позволяет создавать коллективное состояние, состоящее из множества объектов.
Комбинирование анимаций формирует сложные состояния:
const tl = new mojs.Timeline();
tl.add(
new mojs.Shape({ scale: { 0: 1 } }),
new mojs.Shape({ x: { 0: 100 }, delay: 300 })
);
Здесь:
mo.js поддерживает хуки:
circle.then({
onComplete() {
console.log('done');
}
});
События позволяют:
Особенности управления состоянием в mo.js:
Это делает подход:
Сложные интерфейсы строятся через композицию:
Каждый уровень добавляет:
При одинаковых параметрах mo.js гарантирует:
Это особенно важно для:
В связке с React/Vue:
Пример (React-подход):
useEffect(() => {
circle.setProgress(progress);
}, [progress]);
mo.js позволяет постепенно изменять состояние:
setProgresstunethen())Это создаёт гибкую модель:
Для сложных сцен:
timeline1.setProgress(p);
timeline2.setProgress(p);
Это обеспечивает:
Особенности подхода mo.js:
Однако:
Эффективная схема:
Такой подход разделяет:
и делает систему масштабируемой.