Создание пользовательских фигур через path

В библиотеке mo.js пользовательские фигуры строятся вокруг SVG path-данных, где базовой единицей становится строка d из формата SVG Path. Этот подход позволяет использовать любые сложные контуры: иконки, иллюстрации, логотипы и абстрактные формы, сохраняя при этом интеграцию с системой анимаций mo.js.

SVG path представляет собой последовательность команд, описывающих геометрию:

  • M — перемещение пера
  • L — линия
  • C — кубическая кривая Безье
  • Q — квадратичная кривая
  • Z — замыкание контура

В mo.js эти данные используются как источник для отрисовки shape-модуля, который интерпретирует путь и преобразует его в анимационный объект.

const customPath = "M10 10 L50 10 L50 50 L10 50 Z";

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

Интеграция path в Shape модуль mo.js

В mo.js кастомные фигуры подключаются через Shape или через расширение CustomShape. Основная идея заключается в передаче SVG path в конфигурацию shape-объекта.

const square = new mojs.Shape({
  shape: 'polygon',
  points: 4,
  radius: 40,
  fill: 'none',
  stroke: '#4A90E2',
  strokeWidth: 2
});

square.play();

Однако для произвольного path используется другой подход — через CustomShape.

Создание пользовательской фигуры через CustomShape

mo.js позволяет регистрировать кастомные фигуры, которые затем становятся частью системы shape-рендеринга.

mojs.addShape('customStar', function(ctx, ratio) {
  const path = new Path2D("M50 15 L61 35 L84 35 L66 50 L72 72 L50 60 L28 72 L34 50 L16 35 L39 35 Z");

  ctx.strokeStyle = '#FF4D5A';
  ctx.lineWidth = 2;
  ctx.stroke(path);
});

После регистрации фигура становится доступной как обычный shape:

const star = new mojs.Shape({
  shape: 'customStar',
  scale: { 0: 1 },
  duration: 800,
  easing: 'elastic.out'
});

star.play();

Использование SVG path напрямую

mo.js поддерживает работу с path через shape: 'path', где в качестве параметра передается строка d.

const heart = new mojs.Shape({
  shape: 'path',
  path: "M24 4C12-10 -10 18 24 40C58 18 36-10 24 4Z",
  fill: '#E74C3C',
  scale: { 0: 1 },
  duration: 1000
});

heart.play();

Такая форма позволяет использовать любые SVG-иконки без предварительной конвертации в примитивы mo.js.

Морфинг между path-фигурами

Одной из ключевых возможностей является морфинг — плавное преобразование одной формы в другую. Для этого используется интерполяция path-данных.

const morph = new mojs.Shape({
  shape: 'path',
  path: {
    0: "M10 10 L90 10 L90 90 L10 90 Z",
    1: "M50 10 L90 90 L10 90 Z"
  },
  duration: 1200,
  easing: 'cubic.out',
  fill: '#6C5CE7'
});

morph.play();

Интерполяция требует совместимой топологии путей. При различии количества сегментов используется автоматическая нормализация.

Нормализация SVG path

Для корректного морфинга и анимации path проходят этап нормализации:

  • преобразование относительных команд в абсолютные
  • унификация количества точек
  • выравнивание направлений контуров
  • аппроксимация кривых Безье при необходимости

При сложных фигурах часто используется предварительная обработка через инструменты вроде flubber или встроенные механизмы интерполяции mo.js.

Использование Path2D и canvas-рендеринга

Внутренний рендеринг кастомных фигур часто опирается на Path2D, который ускоряет отрисовку на canvas.

const shape = new mojs.Shape({
  shape: 'path',
  path: new Path2D("M20 20 L80 20 L80 80 L20 80 Z"),
  stroke: '#2ECC71',
  strokeWidth: 3
});

Использование Path2D снижает нагрузку при многократной перерисовке в анимациях burst-эффектов.

Анимация path через timeline

Пользовательские фигуры могут быть частью сложных сцен, управляемых через Timeline.

const circle = new mojs.Shape({
  shape: 'circle',
  radius: 30,
  fill: '#3498DB',
  duration: 600
});

const triangle = new mojs.Shape({
  shape: 'path',
  path: "M50 10 L90 90 L10 90 Z",
  fill: '#E67E22',
  duration: 600,
  delay: 200
});

const timeline = new mojs.Timeline();
timeline.add(circle, triangle);
timeline.play();

Такой подход позволяет комбинировать кастомные path-фигуры с базовыми shape-объектами.

Burst-анимации с пользовательскими path

В burst-сценариях path-фигуры используются как элементы частиц. Каждый элемент может наследовать один и тот же path или получать вариации.

const burst = new mojs.Burst({
  radius: { 0: 100 },
  count: 10,
  children: {
    shape: 'path',
    path: "M10 10 L90 10 L90 90 L10 90 Z",
    fill: { '#F1C40F': '#E74C3C' },
    duration: 1000
  }
});

burst.play();

Каждый элемент burst-а может иметь собственные трансформации scale, rotation и opacity.

Генерация path на основе функций

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

function generateWavePath(amplitude, frequency) {
  let d = "M0 50";
  for (let x = 0; x <= 100; x += 10) {
    const y = 50 + Math.sin(x * frequency) * amplitude;
    d += ` L${x} ${y}`;
  }
  return d;
}

const wave = new mojs.Shape({
  shape: 'path',
  path: generateWavePath(20, 0.2),
  stroke: '#1ABC9C',
  fill: 'none',
  duration: 1500
});

wave.play();

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

Оптимизация работы с пользовательскими path

При интенсивной анимации path-фигур критически важны следующие аспекты:

  • минимизация количества узлов в path
  • избегание избыточных кривых Безье
  • кэширование Path2D объектов
  • ограничение количества одновременно анимируемых фигур
  • использование GPU-ускоряемых трансформаций (scale, translate)

Особенно затратными являются морфинги сложных SVG с большим числом сегментов.

Комбинирование path с трансформациями mo.js

Каждая path-фигура может участвовать в стандартной системе трансформаций:

  • scale
  • rotate
  • x, y
  • opacity
const shape = new mojs.Shape({
  shape: 'path',
  path: "M50 10 L90 90 L10 90 Z",
  scale: { 0: 1.2 },
  rotate: { 0: 180 },
  duration: 900,
  easing: 'expo.out'
});

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

Связь path-фигур с интерактивностью

Path может быть связан с событиями DOM или canvas, превращаясь в интерактивный элемент анимационной сцены. Изменение path в ответ на событие позволяет реализовать динамическую реакцию формы на внешние факторы.

document.addEventListener('click', () => {
  shape.tune({
    path: "M20 20 L80 20 L50 80 Z"
  }).replay();
});

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