Добавление анимаций

Анимации в mo.js строятся вокруг принципа декларативного описания движения: разработчик задаёт параметры, а библиотека управляет интерполяцией, таймингом и рендерингом. Основные сущности, отвечающие за анимацию, — Tween, Timeline и набор специализированных классов (Shape, Burst, Html, Swirl), которые наследуют поведение базовых анимационных объектов.

Базовый принцип создания анимации

Любая анимация в mo.js описывается как объект с набором свойств:

  • начальное состояние
  • конечное состояние
  • длительность
  • задержка
  • функция easing
  • параметры повторения

Минимальный пример анимации:

const animation = new mojs.Html({
  el: '.box',
  x: { 0: 200 },
  duration: 1000
});

animation.play();

Здесь происходит ключевая концепция mo.js: свойства записываются как переходы {from: to}. Это позволяет избегать ручного расчёта промежуточных значений.

Интерполяция значений

mo.js автоматически интерполирует числовые значения. Поддерживаются:

  • координаты (x, y)
  • размеры (width, height)
  • прозрачность (opacity)
  • поворот (angle, rotate)
  • цветовые значения (background-color, stroke)

Пример изменения нескольких параметров одновременно:

const animation = new mojs.Html({
  el: '.box',
  x: { 0: 300 },
  y: { 0: -150 },
  opacity: { 1: 0 },
  rotate: { 0: 360 },
  duration: 1200
});

animation.play();

Каждое свойство анимируется синхронно, но может иметь собственную кривую интерполяции при необходимости.

Управление временем выполнения

Время — ключевой параметр любой анимации. В mo.js он задаётся через duration и может комбинироваться с:

  • delay — задержка старта
  • repeat — повтор анимации
  • speed — глобальная скорость
  • isYoyo — возвратное воспроизведение

Пример с задержкой и повторением:

const animation = new mojs.Html({
  el: '.circle',
  scale: { 0: 1 },
  opacity: { 0: 1 },
  duration: 800,
  delay: 300,
  repeat: 3,
  isYoyo: true
});

animation.play();

isYoyo создаёт эффект обратного воспроизведения, позволяя строить циклические анимации без дублирования кода.

Функции плавности (easing)

Easing определяет характер движения: ускорение, замедление, упругость. mo.js поддерживает множество предустановленных функций.

Пример:

const animation = new mojs.Html({
  el: '.box',
  x: { 0: 400 },
  duration: 1000,
  easing: 'elastic.out'
});

animation.play();

Часто используемые типы easing:

  • linear
  • quad.out
  • cubic.inOut
  • back.out
  • elastic.out
  • bounce.out

Easing можно комбинировать с другими параметрами, создавая сложные физические эффекты.

Анимация появления и исчезновения

Часто используемый паттерн — управление прозрачностью и масштабом для появления элементов интерфейса.

const fadeIn = new mojs.Html({
  el: '.modal',
  opacity: { 0: 1 },
  scale: { 0.8: 1 },
  duration: 400,
  easing: 'quad.out'
});

fadeIn.play();

Аналогично строится исчезновение:

const fadeOut = new mojs.Html({
  el: '.modal',
  opacity: { 1: 0 },
  scale: { 1: 0.8 },
  duration: 300
});

fadeOut.play();

Анимация трансформаций

Transform-операции являются основой большинства визуальных эффектов:

  • перемещение (x, y)
  • масштабирование (scale)
  • вращение (rotate, angle)
  • наклон (skewX, skewY)

Комбинированный пример:

const transform = new mojs.Html({
  el: '.card',
  x: { 0: 100 },
  y: { 0: -50 },
  scale: { 1: 1.2 },
  rotate: { 0: 15 },
  duration: 600,
  easing: 'cubic.out'
});

transform.play();

Такие комбинации часто используются для hover-эффектов и микроинтеракций.

Синхронизация нескольких анимаций

mo.js позволяет запускать несколько анимаций одновременно или последовательно через Timeline.

Параллельное выполнение:

const a1 = new mojs.Html({
  el: '.box1',
  x: { 0: 200 },
  duration: 800
});

const a2 = new mojs.Html({
  el: '.box2',
  y: { 0: 200 },
  duration: 800
});

a1.play();
a2.play();

Последовательное выполнение через таймлайн:

const timeline = new mojs.Timeline();

timeline.add(a1, a2);
timeline.play();

Timeline обеспечивает точное управление порядком и синхронизацией сложных сцен.

Использование событий анимации

mo.js предоставляет события жизненного цикла анимации:

  • start
  • update
  • complete

Пример:

const animation = new mojs.Html({
  el: '.box',
  x: { 0: 300 },
  duration: 1000
});

animation
  .then({
    opacity: { 1: 0 },
    duration: 500
  });

animation.play();

Метод then позволяет строить цепочки анимаций без использования внешних таймлайнов.

Динамическое управление анимацией

Анимацию можно запускать, останавливать и перематывать:

const anim = new mojs.Html({
  el: '.box',
  x: { 0: 500 },
  duration: 2000
});

anim.play();

setTimeout(() => anim.pause(), 500);
setTimeout(() => anim.play(), 1000);

Также доступны методы:

  • play()
  • pause()
  • replay()
  • reset()

Это позволяет интегрировать анимации в интерактивные сценарии интерфейса.

Работа с процентным прогрессом

mo.js позволяет управлять анимацией через прогресс:

const anim = new mojs.Html({
  el: '.box',
  x: { 0: 300 },
  duration: 1000
});

anim.setProgress(0.5);

Значение 0.5 означает 50% выполнения анимации. Это полезно при синхронизации с прокруткой или пользовательским вводом.

Комбинирование параметров в сложных сценах

Сложные анимации строятся через композицию:

const box = new mojs.Html({
  el: '.box',
  x: { 0: 300 },
  duration: 800,
  easing: 'cubic.out'
});

const fade = new mojs.Html({
  el: '.box',
  opacity: { 1: 0 },
  duration: 400,
  delay: 400
});

const timeline = new mojs.Timeline();
timeline.add(box, fade);
timeline.play();

Такая структура позволяет разложить сложное движение на независимые слои логики.

Принцип независимости свойств

Одной из ключевых особенностей mo.js является независимость анимируемых свойств. Каждое свойство интерполируется отдельно, что позволяет:

  • комбинировать разные типы движения
  • избегать конфликтов трансформаций
  • строить модульные эффекты

Например, изменение scale не влияет на opacity, даже если они изменяются в разных временных диапазонах.

Итеративное построение анимаций

Часто анимации строятся поэтапно:

  1. базовое движение
  2. добавление трансформации
  3. подключение easing
  4. синхронизация с другими элементами
  5. упаковка в timeline

Такой подход позволяет постепенно усложнять поведение без потери контроля над кодом.

const base = new mojs.Html({
  el: '.item',
  x: { 0: 200 },
  duration: 600
});

const enhanced = new mojs.Html({
  el: '.item',
  x: { 0: 200 },
  scale: { 1: 1.3 },
  rotate: { 0: 10 },
  duration: 600,
  easing: 'back.out'
});

enhanced.play();