В основе работы с библиотекой mo.js лежит идея декларативного описания анимаций через объекты. Такой подход позволяет отделять конфигурацию эффекта от его исполнения и открывает возможность повторного использования одних и тех же анимационных конструкций в разных контекстах интерфейса.
Переиспользование в mo.js строится не вокруг «готовых эффектов», а вокруг фабрик, конфигов и экземпляров анимаций, которые можно многократно создавать, модифицировать и запускать.
Наиболее простая форма переиспользования — выделение конфигурации в отдельную переменную.
const baseOptions = {
left: 0,
top: 0,
radius: { 0: 50 },
duration: 600,
easing: 'cubic.out',
fill: 'transparent',
stroke: '#4F80FF',
strokeWidth: 2
};
const circle = new mojs.Shape({
...baseOptions,
shape: 'circle'
});
const square = new mojs.Shape({
...baseOptions,
shape: 'rect'
});
Здесь базовый набор параметров становится ядром, вокруг которого строятся вариации. Такой подход снижает дублирование и делает поведение анимаций предсказуемым.
Следующий уровень переиспользования — функции-фабрики, возвращающие новые экземпляры анимаций.
function createPulse(color = '#4F80FF', radius = 40) {
return new mojs.Shape({
shape: 'circle',
fill: 'transparent',
stroke: color,
strokeWidth: 2,
radius: { 0: radius },
duration: 500,
easing: 'quad.out'
});
}
Такой подход решает сразу несколько задач:
Использование:
const pulse1 = createPulse('#FF4F4F', 60);
const pulse2 = createPulse('#4F80FF', 40);
pulse1.play();
pulse2.play();
Фабрики особенно полезны при построении UI-систем, где одинаковые эффекты используются в разных компонентах.
.replay() и .reset()mo.js предоставляет встроенные механизмы повторного запуска анимаций без пересоздания экземпляра.
const burst = new mojs.Burst({
radius: { 0: 100 },
count: 8,
children: {
shape: 'circle',
radius: 10,
fill: '#4F80FF'
}
});
burst.play();
Повторное использование:
burst.replay();
Метод .replay():
Метод .reset() используется для возврата в начальное
состояние без запуска:
burst.reset();
Это важно при управлении сложными интерфейсными сценариями, где анимации синхронизируются с событиями пользователя.
Одним из ключевых инструментов композиции является
Timeline. Он позволяет объединять несколько анимаций и
использовать их как единый объект.
const circle = new mojs.Shape({
shape: 'circle',
radius: { 0: 40 },
fill: 'none',
stroke: '#4F80FF'
});
const square = new mojs.Shape({
shape: 'rect',
radius: { 0: 30 },
fill: 'none',
stroke: '#FF4F4F'
});
const timeline = new mojs.Timeline({
repeat: 0
});
timeline.add(circle, square);
Теперь весь набор анимаций управляется централизованно:
timeline.replay();
Переиспользование таймлайнов особенно эффективно в интерфейсах с состояниями:
Прямого глубокого клонирования в mo.js нет, поэтому распространённый паттерн — создание «чистых» фабрик.
function createRing({ color, radius, duration }) {
return new mojs.Shape({
shape: 'circle',
fill: 'transparent',
stroke: color,
strokeWidth: 2,
radius: { 0: radius },
duration
});
}
Использование:
const successRing = createRing({
color: '#2ECC71',
radius: 80,
duration: 700
});
const errorRing = createRing({
color: '#E74C3C',
radius: 80,
duration: 700
});
Такой подход заменяет необходимость копирования объектов и снижает риск ошибок, связанных с состоянием экземпляров.
В больших проектах целесообразно выделять глобальные пресеты анимаций.
const presets = {
fastFade: {
duration: 200,
easing: 'linear.none'
},
smoothPop: {
duration: 600,
easing: 'cubic.out'
},
elastic: {
duration: 900,
easing: 'elastic.out'
}
};
Использование:
const pop = new mojs.Shape({
...presets.smoothPop,
shape: 'circle',
radius: { 0: 50 },
fill: '#4F80FF'
});
Преимущества такого подхода:
.tune()Метод .tune() позволяет изменять параметры уже созданной
анимации без её пересоздания.
const shape = new mojs.Shape({
shape: 'circle',
radius: 40,
fill: '#4F80FF'
});
Изменение параметров перед повторным запуском:
shape.tune({
fill: '#FF4F4F',
radius: 60
}).replay();
Это особенно важно в сценариях, где один и тот же эффект применяется к разным элементам UI.
Когда требуется массовое управление анимациями, используется хранение экземпляров в структурах данных.
const animations = [];
document.querySelectorAll('.dot').forEach((el) => {
const anim = new mojs.Shape({
el,
shape: 'circle',
radius: { 0: 20 },
duration: 400
});
animations.push(anim);
});
Теперь можно управлять всеми анимациями централизованно:
animations.forEach(anim => anim.replay());
Такой подход используется в системах:
Сильнейший способ переиспользования — создание составных эффектов из базовых анимаций.
function createSuccessEffect() {
const burst = new mojs.Burst({
radius: { 0: 100 },
count: 10,
children: {
shape: 'circle',
fill: '#2ECC71',
radius: 8
}
});
const ring = new mojs.Shape({
shape: 'circle',
radius: { 0: 80 },
fill: 'transparent',
stroke: '#2ECC71',
strokeWidth: 3
});
return new mojs.Timeline().add(burst, ring);
}
Использование:
const success = createSuccessEffect();
success.replay();
Композиция позволяет создавать высокоуровневые эффекты, не теряя контроля над низкоуровневыми деталями.
Часто анимации связываются с DOM-событиями и используются многократно без пересоздания.
const clickAnim = new mojs.Shape({
shape: 'circle',
radius: { 0: 30 },
fill: '#4F80FF',
duration: 400
});
button.addEventListener('click', () => {
clickAnim.replay();
});
Такой подход уменьшает накладные расходы и повышает отзывчивость интерфейса.
При масштабировании системы важно отделять логику создания анимаций от их запуска.
const animationsMap = {
success: createSuccessEffect,
error: () => new mojs.Shape({
shape: 'circle',
radius: { 0: 60 },
stroke: '#E74C3C'
})
};
Использование:
function playAnimation(type) {
const animFactory = animationsMap[type];
const anim = animFactory();
anim.replay();
}
Это создаёт гибкую систему, где добавление нового эффекта не затрагивает существующий код.
Для сложных систем применяется многослойная конфигурация:
const base = {
duration: 500,
easing: 'cubic.out'
};
const interactive = {
...base,
duration: 300
};
const emphasis = {
...base,
duration: 900,
easing: 'elastic.out'
};
Каждый слой наследует предыдущий, создавая управляемую иерархию параметров.
Эффективная работа с mo.js строится на том, что анимации рассматриваются не как разовые эффекты, а как переиспользуемые модули. Это выражается в:
Такой подход позволяет строить сложные интерфейсы, в которых анимация становится частью системной логики, а не изолированным визуальным украшением