Исключение элементов из анимации

Исключение отдельных элементов из SVG-анимации в Vivus обычно решается не через отдельную встроенную опцию библиотеки, а через контроль набора DOM-элементов, которые попадают под анимацию. Vivus работает непосредственно с путями SVG (<path>), изменяя их stroke-dasharray и stroke-dashoffset, поэтому ключевая точка управления — выбор тех элементов, которые передаются в анимационный контекст.

Vivus при инициализации проходит по SVG-дереву и собирает элементы, которые могут быть анимированы. В первую очередь это:

  • <path>
  • иногда <line>, <polyline>, <polygon> (в зависимости от конфигурации и трансформации)

Любой элемент, попавший в этот набор, становится частью общей последовательности отрисовки. Следовательно, исключение элемента из анимации сводится к тому, чтобы он:

  • не был выбран при инициализации
  • или был преобразован так, чтобы не интерпретироваться как анимируемый путь
  • или был физически исключён из SVG-дерева перед запуском Vivus

Фильтрация элементов перед передачей в Vivus

Наиболее прямой способ — заранее отфильтровать DOM-элементы и оставить только те, которые должны анимироваться.

const svg = document.querySelector('svg');

// выбор всех путей
const paths = svg.querySelectorAll('path');

// исключение элементов с классом "no-anim"
const filteredPaths = Array.from(paths).filter(path => {
  return !path.classList.contains('no-anim');
});

Далее возможны два варианта использования:

  1. Передача SVG целиком в Vivus, но с предварительным удалением ненужных элементов
  2. Создание отдельного контейнера только с нужными путями

Удаление нежелательных элементов:

paths.forEach(path => {
  if (path.classList.contains('no-anim')) {
    path.remove();
  }
});

new Vivus('my-svg', {
  type: 'oneByOne',
  duration: 120
});

Этот подход фактически исключает элементы из DOM-дерева, а значит Vivus их не увидит.

Использование CSS-классов как маркеров исключения

Часто SVG содержит логическую структуру, где некоторые элементы должны оставаться статичными (например, фоновые формы, декоративные элементы или текст). Для этого применяется соглашение о классах:

<svg id="my-svg">
  <path d="..." class="animate"></path>
  <path d="..." class="no-anim"></path>
</svg>

И фильтрация выполняется через querySelectorAll:

const svg = document.getElementById('my-svg');

const animatable = svg.querySelectorAll('path:not(.no-anim)');

animatable.forEach(p => {
  p.style.strokeDasharray = p.getTotalLength();
  p.style.strokeDashoffset = p.getTotalLength();
});

После этого Vivus можно запускать только на подготовленном SVG, где исключённые элементы уже не участвуют в расчёте.

Разделение SVG на логические группы

SVG поддерживает группировку через <g>, что позволяет разделять анимируемые и неанимируемые части структуры.

<svg id="logo">
  <g class="static-layer">
    <path d="..."></path>
  </g>

  <g class="animated-layer">
    <path d="..."></path>
    <path d="..."></path>
  </g>
</svg>

Далее анимация применяется только к нужной группе:

const svg = document.getElementById('logo');
const animatedGroup = svg.querySelector('.animated-layer');

new Vivus(animatedGroup, {
  type: 'delayed',
  duration: 150
});

Такой подход даёт структурное разделение логики: статические элементы вообще не попадают в контекст анимации.

Исключение через дублирование SVG-контейнеров

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

  • первый SVG содержит только статическую часть
  • второй SVG содержит только анимируемые пути
<svg id="static-logo">
  <path d="..."></path>
</svg>

<svg id="animated-logo">
  <path d="..."></path>
</svg>
new Vivus('animated-logo', {
  type: 'oneByOne',
  duration: 200
});

Этот метод особенно полезен при работе с логотипами и иллюстрациями, где пересекаются декоративные и анимационные слои.

Манипуляция через атрибуты данных

SVG-элементы могут содержать произвольные атрибуты data-*, которые удобно использовать как флаги исключения:

<path d="..." data-vivus-ignore="true"></path>
<path d="..."></path>

Фильтрация:

const svg = document.getElementById('icon');

const paths = svg.querySelectorAll('path');

paths.forEach(path => {
  if (path.dataset.vivusIgnore === "true") {
    path.remove();
  }
});

Подход удобен тем, что не перегружает CSS-классы и не конфликтует со стилями.

Исключение сложных элементов через преобразование геометрии

Некоторые SVG-элементы (например, текст или сложные фигуры) автоматически конвертируются в пути при экспорте. Если требуется исключить их из анимации, применяется стратегия предварительного преобразования:

  • текст переводится в контуры до попадания в Vivus
  • декоративные элементы сохраняются в отдельном слое
  • сложные составные формы упрощаются

В результате остаются только те пути, которые должны быть анимированы.

Управление через выборочный список путей

В случаях, когда требуется строгий контроль, используется явный список селекторов:

const svg = document.getElementById('icon');

const allowed = [
  '#icon .line-1',
  '#icon .line-2',
  '#icon .main-outline'
];

const paths = svg.querySelectorAll(allowed.join(','));

new Vivus('icon', {
  type: 'sync',
  duration: 100
});

Такой подход исключает любую неопределённость: анимации подвергаются только перечисленные элементы.

Влияние структуры SVG на исключение элементов

Глубина и сложность SVG напрямую влияют на простоту управления исключениями:

  • плоская структура затрудняет фильтрацию
  • слоистая структура через <g> упрощает контроль
  • наличие семантических классов делает исключение детерминированным

Оптимальная архитектура SVG для Vivus всегда предполагает разделение на логические группы до этапа анимации.

Побочные эффекты неправильного исключения

Некорректное исключение элементов может приводить к:

  • нарушению последовательности отрисовки
  • смещению длительности анимации
  • неравномерному распределению stroke-dashoffset
  • визуальным разрывам в композиции

Особенно это заметно при использовании oneByOne, где порядок обхода путей строго влияет на восприятие анимации.

Комбинирование подходов

На практике применяется комбинация нескольких техник:

  • маркировка через классы
  • разделение через <g>
  • удаление DOM-элементов до инициализации
  • выборочный querySelector
  • разбиение SVG на слои

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