Специфика работы с SVG

SVG-анимация в Motion One опирается на две фундаментальные особенности: декларативную природу SVG-атрибутов и возможность низкоуровневого управления трансформациями через CSS-подобную модель. В отличие от HTML-элементов, SVG требует учёта собственной системы координат, специфики рендеринга контуров и различий между атрибутами и стилями.


Особенности SVG как графической модели

SVG (Scalable Vector Graphics) использует математическое описание графики, где каждый элемент существует в координатном пространстве, заданном через viewBox.

Ключевые особенности:

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

Эти особенности напрямую влияют на поведение Motion One при анимации SVG-элементов.


Анимация SVG через Motion One

Motion One предоставляет единый API animate, который работает с SVG-элементами так же, как с DOM-узлами, но с рядом нюансов.

import { animate } from "motion"

animate("circle", {
  cx: [0, 200],
  cy: [0, 200],
  r: [10, 50]
})

Здесь анимация происходит через изменение атрибутов SVG (cx, cy, r), а не только CSS-свойств.


Атрибуты vs стили в SVG

SVG поддерживает два механизма управления свойствами:

Атрибуты (presentation attributes)

  • x, y
  • cx, cy
  • r
  • fill, stroke
  • stroke-width

CSS-стили

  • transform
  • opacity
  • filter
  • visibility

Motion One автоматически определяет тип свойства и применяет корректный способ интерполяции.


Transform в SVG и система координат

Одной из ключевых проблем SVG-анимации является поведение transform.

SVG использует локальные системы координат, и поэтому:

  • translate зависит от viewBox
  • scale влияет на толщину stroke
  • rotate требует явного указания центра

Важный нюанс transform-origin

В SVG по умолчанию transform-origin не совпадает с HTML-моделью.

Правильная настройка:

animate(".icon", {
  rotate: 180
}, {
  transformOrigin: "50% 50%"
})

или через CSS:

.icon {
  transform-box: fill-box;
  transform-origin: center;
}

Анимация контуров (stroke-dasharray)

Одна из наиболее распространённых техник SVG-анимации — “рисование линии”.

SVG-путь можно анимировать через:

  • stroke-dasharray
  • stroke-dashoffset

Принцип работы

Контур разбивается на “пунктир”, где длина штриха равна длине пути.

import { animate } from "motion"

const path = document.querySelector("path")
const length = path.getTotalLength()

path.style.strokeDasharray = length
path.style.strokeDashoffset = length

animate(path, {
  strokeDashoffset: [length, 0]
}, {
  duration: 2
})

Motion One корректно интерполирует числовые значения, обеспечивая плавное “прорисовывание”.


Работа с <path> и сложной геометрией

SVG <path> является наиболее сложным элементом, поскольку описывает кривые Безье и сегменты.

Motion One не модифицирует сам d напрямую в базовом сценарии, но поддерживает:

  • анимацию трансформаций пути
  • морфинг через совместимые значения d (при одинаковой структуре)
  • синхронизацию с motion timeline

Пример:

animate("path", {
  d: [
    "M10 10 H 90",
    "M10 10 H 90 V 90"
  ]
})

Координатная система и viewBox

SVG масштабируется через viewBox, что создаёт отдельную систему координат:

<svg viewBox="0 0 100 100">

При анимации важно учитывать:

  • значения x/y/cx/cy всегда в координатах viewBox
  • масштабирование контейнера не влияет на численные ключи анимации
  • stroke может визуально “менять толщину” при scale

Motion One интерполирует значения в логическом пространстве, а не в пикселях.


Анимация групп <g>

Группы SVG позволяют применять трансформации к набору элементов:

animate("g", {
  rotate: 360,
  scale: 1.2
})

Особенность:

  • трансформации наследуются
  • дочерние элементы сохраняют локальные координаты
  • performance лучше, чем анимация каждого элемента отдельно

Fill и stroke: различия в анимации

Fill

  • поддерживает цветовые переходы
  • интерполяция RGB/HSL
  • хорошо работает с opacity

Stroke

  • требует учёта толщины
  • может масштабироваться вместе с transform
  • часто комбинируется с dash-анимацией

Пример:

animate("rect", {
  fill: ["#ff0000", "#0000ff"],
  strokeWidth: [1, 5]
})

Масштабирование и preserveAspectRatio

SVG может вести себя по-разному в зависимости от:

preserveAspectRatio="xMidYMid meet"

При анимации важно учитывать:

  • изменение размера контейнера не сбрасывает анимацию
  • координаты остаются в системе viewBox
  • трансформации не зависят от физического размера

Motion Path (движение по траектории)

Motion One поддерживает движение элементов вдоль пути.

animate(".dot", {
  offsetDistance: [0, 1]
}, {
  offsetPath: "path('M10 80 C 40 10, 65 10, 95 80')"
})

Ключевые особенности:

  • используется нормализованная длина пути (0–1)
  • траектория может быть любой сложности
  • направление вычисляется по касательной

Производительность SVG-анимаций

SVG может быть как очень быстрым, так и проблемным в зависимости от подхода.

Оптимизационные принципы:

  • избегать частой анимации filter
  • минимизировать пересчёт d у path
  • использовать transform вместо координатных атрибутов
  • группировать элементы через <g>
  • уменьшать количество repaint операций

Motion One использует requestAnimationFrame, что снижает нагрузку на main thread.


Анимация opacity и visibility

SVG поддерживает стандартные свойства прозрачности:

animate("circle", {
  opacity: [0, 1]
})

Особенности:

  • visibility не интерполируется, а переключается
  • opacity может комбинироваться с transform
  • групповые изменения распространяются вниз по дереву

Совмещение SVG и DOM-анимации

Motion One позволяет синхронно анимировать SVG и HTML-элементы:

animate(".panel", { x: 100 })
animate("circle", { cx: 100 })

Это важно при создании интерфейсов, где SVG выступает частью UI, а не изолированной графикой.


Особенности интерполяции значений

Motion One использует типизированную интерполяцию:

  • числа → линейная интерполяция
  • цвета → цветовые пространства
  • пути → структурный морфинг
  • трансформации → матричная композиция

SVG добавляет дополнительные ограничения:

  • смешивание единиц невозможно (px vs %)
  • некоторые атрибуты требуют абсолютных значений
  • path требует совместимой структуры

Типичные ошибки при работе с SVG

  • анимация width/height вместо viewBox
  • попытка масштабировать stroke без учета transform-box
  • использование CSS transform без задания origin
  • морфинг несовместимых path
  • смешивание координатных систем

Использование keyframes в SVG

Motion One поддерживает ключевые кадры:

animate("circle", {
  cx: [10, 50, 90],
  cy: [10, 80, 10]
}, {
  duration: 3
})

Особенности:

  • ключевые точки интерполируются последовательно
  • SVG-атрибуты обновляются синхронно
  • можно комбинировать с easing

SVG как система анимационного слоя

В связке с Motion One SVG перестаёт быть статической графикой и превращается в координатную систему анимации, где:

  • элементы — это параметры
  • пути — траектории
  • группы — сцены
  • трансформации — управляющие матрицы

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