Создание веб‑анимаций с mo.js: практический гайд
К чему это пригодится
mo.js подходит для реактивных эффектов на кнопках, фоновых анимаций, эффектов при клике, переходов и небольших motion‑компонентов интерфейса. Библиотека позволяет создавать сложные композиции с минимальным кодом и интегрируется в современные проекты на HTML/CSS/JS.
Введение
Если вы собираетесь запустить собственный сайт, красивые анимации помогут ему выделяться. Анимации можно получить разными способами: от простого GIF до сложных роликов в Blender. Для веб‑проекта удобнее создавать анимации программно — средствами CSS или JavaScript. Среди JavaScript‑библиотек одна из интересных и простых для старта — mo.js.
В этом руководстве вы пройдёте от простых фигур до интерактивной композиции, которая реагирует на клики пользователя.
Мы будем использовать CodePen в качестве среды разработки, потому что он позволяет редактировать HTML/CSS/JS в одном окне. Любой другой редактор подойдёт также. Полный код приведён в примерах по ходу статьи.
При настройке нового Pen откройте «Настройки» и перейдите на вкладку «JavaScript». Выберите препроцессор Babel и добавьте внешнюю библиотеку mo.js через «Add External Scripts/Pens» (в поле поиска введите mo.js).
Важно: Babel позволяет использовать современные возможности JavaScript и делает синтаксис более читабельным для браузеров, которые иначе не поддерживали бы некоторые фичи.
Первые фигуры в mo.js
Перед тем как начать анимировать, изменим фон для лучшей видимости. В CSS‑панели добавьте:
body{
background: rgba(11,11,11,1);
}Создание фигуры в mo.js — атомарная операция. Простейшая фигура — Shape. Добавим её в JS:
const redCirc = new mojs.Shape({
isShowStart:true
});Здесь мы создаём константу redCirc и присваиваем ей экземпляр mojs.Shape. Параметр isShowStart:true заставляет фигуру появиться сразу при создании. По умолчанию Shape — круг в центре экрана.
Чтобы изменить форму, передаём свойство shape:
const redCirc = new mojs.Shape({
isShowStart:true,
shape:'rect'
});Теперь вместо круга отрисуется квадрат.
Добавлять новые свойства в объект просто — перечисляйте пары ключ: значение через запятую. Следующий шаг — сделать анимацию более интересной.
Основы движения
Создадим круг со строкой (обводкой) и без заливки:
const redCirc = new mojs.Shape({
isShowStart:true,
stroke:'red',
strokeWidth:5,
fill:'none',
radius:15
});Здесь мы задали цвет обводки, её ширину и радиус круга. Чтобы добавить движение, используем дельты (начальное и конечное значение):
radius: {15:30},
opacity: {1:0},
duration:1000Delta‑объекты в mo.js задают анимацию свойства с момента A до B. Но это ещё не воспроизводится автоматически — нужно вызвать .play():
// ...конфигурация
}).play();Порядок и сглаживания
Чтобы разделить последовательные анимации, используйте .then(). Пример:
const redCirc = new mojs.Shape({
isShowStart:true,
stroke:'red',
strokeWidth:5,
fill:'none',
radius: 15,
duration:1000
}).then({
//do more stuff here
}).play();.then() позволяет отложить следующий набор команд. Пример эффектного исчезновения:
//do more stuff here
strokeWidth: 0,
scale: { 1: 2, easing: 'sin.in' },
duration: 500Здесь применяется easing ‘sin.in’ — синусоидальное сглаживание. Mo.js поддерживает множество easing‑кривых и позволяет добавлять свои. Для визуального резюме кривых полезен ресурс easings.net.
Burst — взрыв из форм
Burst — коллекция дочерних фигур, вылетающих из центра. Даже пустой Burst уже будет работать:
const sparks = new mojs.Burst({
}).play();Добавим радиус и вращение:
const sparks = new mojs.Burst({
radius: {0:30, easing:'cubic.out'},
angle:{0: 90,easing:'quad.out'},
}).play();Теперь настроим дочерние элементы:
const sparks = new mojs.Burst({
radius: {0:30, easing:'cubic.out'},
angle:{0: 90,easing:'quad.out'},
count:50,
children:{
shape: 'cross',
stroke: 'white',
points: 12,
radius:10,
fill:'none',
angle:{0:360},
duration:300
}
}).play();Дочерние свойства совпадают с настройками Shape; их название и смысл одинаковы. Если исходная анимация redCirc длится слишком долго по сравнению со взрывом, уравняйте их продолжительности для совмещения эффектов.
Основное событие — реакция на клик
Теперь привяжем анимации к клику пользователя. В конце блока JS добавьте прослушиватель событий:
document.addEventListener( 'click', function(e) {
});Внутри слушателя вызовем .tune() и .replay() для каждой сущности:
document.addEventListener( 'click', function(e) {
redCirc
.tune({ x: e.pageX, y: e.pageY, })
.replay();
sparks
.tune({ x: e.pageX, y: e.pageY })
.replay();
});.tune() передаёт новые параметры в объект (например координаты), .replay() перезапускает анимацию с начала при каждом клике.
После пробного запуска вы заметите две проблемы: фигура появляется в центре страницы сразу и анимация смещена вниз и вправо относительно курсора. Решение:
- Удалите .play() у тех объектов, которые вы хотите запускать только по клику.
- Уберите isShowStart:true для тех объектов, которые не должны появляться при загрузке.
- Явно задайте left: 0 и top: 0 для объектов, чтобы убрать привязку к центру страницы:
left: 0,
top: 0,Теперь позиции будут задаваться только через .tune({x, y}).
Важно: после добавления новых объектов не забывайте регистрировать их в обработчике клика.
Психоделика — вращающиеся треугольники
Добавим крупный Burst с многоуровневой окраской и быстрым вращением:
const triangles = new mojs.Burst({
radius: { 0 : 1000,easing: 'cubic.out'},
angle: {1080 : 0,easing: 'quad.out'},
left: 0, top: 0,
count: 20,
children : {
shape: 'polygon',
points: 3,
radius: { 10 : 100 },
fill: ['red','yellow','blue','green'],
duration: 3000
}
});Здесь shape: ‘polygon’ и points: 3 создают треугольники. Массив цветов в fill циклично применяется к детям.
Танцующие пятиугольники
Аналогично создадим pentagons и добавим задержку, чтобы создать наложение эффектов:
const pentagons = new mojs.Burst({
radius: { 0 : 1000,easing: 'cubic.out'},
angle: {0 : 720,easing: 'quad.out'},
left: 0, top: 0,
count: 20,
children : {
shape: 'polygon',
radius: { 1 : 300 },
points: 5,
fill: ['purple','pink','yellow','green'],
delay:500,
duration: 3000
}
});Небольшая задержка делает композицию более интересной: сначала треугольники, затем пятиугольники, визуально создаётся ощущение совместного вращения.
Немножко случайности
Добавим burst с параметрами, зависящими от случайных значений:
const redSparks = new mojs.Burst({
left: 0, top: 0,
count:8,
radius: { 150: 350 },
angle: {0:90 ,easing:'cubic.out'},
children: {
shape: 'line',
stroke: {'red':'transparent'},
strokeWidth: 5,
scaleX: {0.5:0},
degreeShift: 'rand(-90, 90)',
radius: 'rand(20, 300)',
duration: 500,
delay: 'rand(0, 150)',
}
});При использовании случайных значений не забудьте вызывать .generate() перед .replay(), чтобы заново пересчитывать случайные параметры при каждом вызове:
redSparks
.tune({ x: e.pageX, y: e.pageY })
.replay()
.generate();Без .generate() случайные числа зафиксируются при первом создании и повторятся при каждом клике, что нарушит задуманный эффект.
Stagger — последовательная эмиссия элементов
С помощью stagger можно задавать шаг задержки между рождением дочерних объектов. Пример — эффект «колеса Катерины»:
const lines = new mojs.Burst({
radius: { 0 : 1000,easing: 'cubic.out'},
angle: {0 : 1440,easing: 'cubic.out'},
left: 0, top: 0,
count: 50,
children : {
shape: 'line',
radius: { 1 : 100,easing:'elastic.out' },
fill: 'none',
stroke: ['red','orange'],
delay:'stagger(10)',
duration: 1000
}
});stagger(10) даёт по 10 мс между стартами каждого дочернего элемента. Этот приём полезен для создания волновых и вращающихся паттернов.
Умные квадраты
Последний burst использует rect и растянутые по X элементы:
const redSquares = new mojs.Burst({
radius: { 0 : 1000,easing: 'cubic.out'},
angle: {360 : 0,easing: 'quad.out'},
left: 0, top: 0,
count: 20,
children : {
shape: 'rect',
radiusX: { 1 : 1000 },
radiusY:50,
points: 5,
fill: 'none',
stroke: {'red':'orange'},
strokeWidth:{5:15},
delay:1000,
duration: 3000
}
});Именно в таких неожиданных комбинациях форм и параметров рождаются приятные геометрические узоры.
Итоговые рекомендации по использованию
mo.js — мощный инструмент для мелких и средних motion‑задач на сайте. Он не заменит After Effects для кинематографичных роликов, но отлично подходит для интерактивных эффектов, где важна реакция пользователя.
Когда mo.js хорошая идея
- Быстрые эффекты при клике, наведении и при переходах.
- Декоративные фоны и узоры, создаваемые программно.
- Простые, повторяемые визуальные паттерны с контролем времени и easing.
Когда лучше выбрать другое решение
- Если вам нужен сложный compositing, цветокоррекция и трекинг — используйте профессиональные инструменты (After Effects, Nuke).
- Для глобальных анимаций интерфейса на уровне компонентов (React/Vue) может быть удобнее использовать специализированные motion‑библиотеки, интегрированные с фреймворком (например, Framer Motion для React).
- Для тяжёлых Canvas/WebGL‑визуализаций с большим количеством частиц лучше смотреть в сторону WebGL‑библиотек (Pixi.js, Three.js).
Альтернативы и сочетания
- CSS анимации: отличны для простых трансформаций (translate/scale/opacity) и минимального JS.
- GreenSock (GSAP): более зрелая и гибкая библиотека для сложных анимаций с богатой экосистемой плагинов.
- Anime.js: простой API и хороший выбор кривых easing.
- Three.js + GLSL: если нужна 3D или шейдерная графика.
Выбор зависит от задачи: mo.js хорош для векторных, декларативных и «взрывных» эффектов с быстрым прототипированием.
Ментальные модели и эвристики
- Разделяй и властвуй: разбивайте композицию на независимые объекты (shape, burst, layer).
- Управляй временем: синхронизируйте продолжительности, задержки и порядок — это ключ к «картинке», которая выглядит профессионально.
- Контраст и иерархия: используйте разные масштабы и цвета, чтобы главный элемент привлекал внимание.
- Умеренность: слишком много наброшенных эффектов быстро утомляет.
Мини‑методология создания анимации (шаги)
- Определите цель: наведение внимания, обратная связь, украшение.
- Прототип в CodePen: начните с одной фигуры и простого burst.
- Синхронизируйте длительности и delays.
- Добавьте случайность и stagger для разнообразия.
- Тестируйте на медленных устройствах.
- Оптимизируйте (уменьшайте count, упрощайте фигуры).
- Интегрируйте в приложение как компонент.
Чек‑лист ролей
Дизайнер:
- Описал цель эффекта и поведение на разных экранах.
- Подобрал палитру и вариативность цветов.
- Определил длительности и ключевые кадры.
Разработчик:
- Подключил mo.js через CDN/пакет.
- Выделил эффект в отдельный модуль/компонент.
- Обеспечил graceful degradation для старых браузеров.
- Добавил тесты приёмки и переработал производительность.
Продакт‑менеджер:
- Сформулировал критерии приёмки.
- Проверил, что эффект не мешает основному UX.
Критерии приёмки
- Анимация корректно запускается по клику в пределах видимой области.
- Эффект не вызывает значительного падения FPS на целевых устройствах.
- Все элементы возвращаются в консистентное состояние после завершения анимации.
- Для пользовательной доступности (a11y) сохранён фокус и нет неожиданных смещений контента.
Тесты и примеры приёмки
- Тест 1: Запустить анимацию на мобильном устройстве (CPU throttling) — должно оставаться >20 FPS для комфортного UX.
- Тест 2: 100 последовательных кликов — не должно быть накапливающихся объектов в DOM.
- Тест 3: Проверка координат — эффект стартует в точке клика, без смещения.
- Тест 4: Отключённый JavaScript — контент остаётся доступным и понятным.
Производительность и оптимизация
- Ограничьте count у Burst на мобильных устройствах.
- Используйте простые фигуры вместо сложных полигонов, если нужно сохранить FPS.
- Минимизируйте одновременно работающие анимации.
- Профилируйте в DevTools: внимание к repaint/paint и composite.
Совместимость и миграция
- mo.js работает в современных браузерах. Для поддержки старых версий используйте полифиллы или Babel при сборке.
- При миграции с других библиотек разделяйте логику анимации и состояния приложения, чтобы не блокировать UI-фреймворк.
Примеры кода — полный рабочий шаблон (обобщённый)
Привожу ключевые фрагменты, которые складываются в интерактивную сцену (не забудьте подключить mo.js и Babel в настройках Pen):
/* CSS */
body{
background: rgba(11,11,11,1);
}
/* JS */
const redCirc = new mojs.Shape({
left:0, top:0,
stroke:'red',
strokeWidth:5,
fill:'none',
radius:15,
radius:{15:30},
opacity:{1:0},
duration:1000
});
// sparks, triangles, pentagons, redSparks, lines, redSquares
// (те же конфигурации, что описаны выше)
document.addEventListener('click', function(e){
redCirc.tune({ x:e.pageX, y:e.pageY }).replay();
sparks.tune({ x:e.pageX, y:e.pageY }).replay();
triangles.tune({ x:e.pageX, y:e.pageY }).replay();
pentagons.tune({ x:e.pageX, y:e.pageY }).replay();
redSparks.tune({ x:e.pageX, y:e.pageY }).generate().replay();
lines.tune({ x:e.pageX, y:e.pageY }).replay();
redSquares.tune({ x:e.pageX, y:e.pageY }).replay();
});Этот шаблон показывает, как группировать и запускать разные куски анимации из одного обработчика событий.
Decision‑flow для выбора подхода к анимации
flowchart TD
A[Нужна ли интерактивность?] -->|Да| B{Сложность эффектов}
B -->|Простые трансформации| C[CSS animation/transition]
B -->|Декоративные векторные| D[mo.js]
B -->|Сложная временная логика| E[GSAP]
B -->|3D или шейдеры| F[Three.js / WebGL]
A -->|Нет, только автоплей| G[CSS or Lottie]Безопасность и приватность
- mo.js сам по себе не обрабатывает персональные данные.
- Если вы вычисляете координаты клика и отправляете события на сервер — соблюдайте политику приватности и минимизируйте сбор данных.
Короткая памятка (cheat sheet)
- .play() — запускает анимацию один раз с момента создания.
- .replay() — перезапуск при каждом вызове.
- .tune(obj) — изменяет параметры объекта.
- .generate() — пересчитывает случайные значения (важно при rand()).
- Delta‑объекты: radius: {from:to} — задают анимацию конкретного свойства.
1‑строчный глоссарий
- Burst — взрыв/эмиссия дочерних фигур;
- Shape — базовая фигура mo.js;
- tune — подстройка параметров;
- replay — перезапуск анимации;
- stagger — последовательные задержки между дочерними элементами;
- rand — генерация случайных значений для свойств.
Social preview и краткое объявление для команды
OG заголовок: Mo.js: быстрый старт для веб‑анимаций
OG описание: Создавайте интерактивные и красивые анимации с mo.js — пошаговый гайд, шаблоны и чек‑листы.
Короткое объявление (100–200 слов):
Новый гайд по mo.js помогает быстро перейти от идеи к рабочей интерактивной анимации. В нём есть примеры burst‑эффектов, работа с событиями, случайности и stagger, а также рекомендации по тестированию и оптимизации. Подходит для дизайнеров и разработчиков, которые хотят добавить динамические визуальные эффекты на сайт без тяжёлых инструментов.
Заключение
mo.js даёт простой и выразительный набор инструментов для создания веб‑анимаций. Он идеален, когда нужно добавить интерактивный визуальный отклик пользователю или декоративные узоры. Начните с простого Shape и по мере уверенности усложняйте композиции: Burst, random, stagger и tune — основные строительные блоки. Экспериментируйте, тестируйте на различных устройствах и помните о сохранении производительности.
Ключевые выводы внизу помогут при быстром чек‑апе.
Important: не забывайте удалять .play() у объектов, которые должны запускаться только по событию, и вызывать .generate() при использовании rand().
Список основных выводов
- mo.js удобен для интерактивных векторных эффектов.
- tune + replay — базовый паттерн для реакций на событие.
- rand + generate() дают вариативность; stagger создаёт волновые эффекты.
- Тестируйте производительность и ограничивайте count на мобильных устройствах.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone