Пунктирные линии

SVG в браузере предоставляет два ключевых механизма управления пунктирными линиями: stroke-dasharray и stroke-dashoffset. Именно на их основе библиотека Vivus реализует эффект «прорисовки» контура, создавая иллюзию того, что линия появляется постепенно, как будто её рисуют вручную.

Каждый путь в SVG можно представить как непрерывную геометрическую кривую, которая визуально формируется с помощью обводки (stroke). Параметры пунктирности позволяют разбить эту обводку на повторяющиеся сегменты.

stroke-dasharray определяет структуру чередования «штрихов» и «пробелов».

Пример:

<path d="M10 10 H 300" stroke="black" stroke-dasharray="10 5" />

В этом случае линия будет состоять из отрезка длиной 10 единиц и пробела длиной 5 единиц, повторяющихся по всей траектории.

Если задать одно число:

stroke-dasharray="20"

то создаётся равномерный паттерн: 20 единиц линии и 20 единиц пробела.


Смещение штрихов и эффект скрытой линии

Второй ключевой параметр — stroke-dashoffset. Он смещает начальную точку штрихов вдоль пути.

Если длина пути полностью покрыта одним «пунктиром», можно скрыть всю линию, сдвинув штрихи за пределы видимой области:

stroke-dasharray="1000"
stroke-dashoffset="1000"

В таком состоянии линия становится полностью невидимой, несмотря на наличие stroke.

Постепенное уменьшение stroke-dashoffset создаёт эффект появления:

1000 → 0

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

Vivus использует именно комбинацию stroke-dasharray + stroke-dashoffset, но автоматизирует вычисление длины пути.

Основная логика:

  1. Вычисляется длина каждого SVG path через getTotalLength()

  2. Устанавливается:

    stroke-dasharray = pathLength
    stroke-dashoffset = pathLength
  3. Значение stroke-dashoffset анимируется до 0

Таким образом каждая линия становится «завёрнутой» в невидимый контур, который постепенно разворачивается.


Поведение пунктирных линий при анимации

При использовании Vivus важно учитывать, что SVG path может иметь:

  • сложные кривые (Bezier)
  • составные контуры
  • несколько подпутей
  • группы <g>

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


Конфигурация Vivus для работы с пунктирными линиями

Базовый вызов:

new Vivus('svgElement', {
  type: 'delayed',
  duration: 200,
  animTimingFunction: Vivus.EASE
});

Хотя библиотека скрывает работу с dash-параметрами, внутренняя логика остаётся той же: установка полного смещения и его постепенное уменьшение.


Типы анимации и влияние на dashoffset

Vivus поддерживает несколько режимов, которые по-разному управляют изменением stroke-dashoffset.

Одновременная анимация

Все элементы начинают и заканчивают прорисовку одновременно. Dash-offset изменяется синхронно для всех путей.

Последовательная анимация

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

Асинхронная анимация

Пути начинают анимацию с небольшими задержками, создавая ощущение естественного рисования.


Тонкости вычисления длины пути

Метод getTotalLength() возвращает точную длину SVG-пути в пикселях, но есть особенности:

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

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


Пунктир как основа эффекта рисования

Ключевая идея: реальная пунктирная линия используется как маска.

Схема:

полный путь
→ превращается в один большой «штрих»
→ смещается за пределы видимости
→ постепенно возвращается

Это превращает обычную линию в управляемый анимационный объект.


Практика комбинирования dash-параметров

Несмотря на то, что Vivus сам управляет stroke-dasharray, ручная настройка может усиливать визуальные эффекты.

Имитация рукописного стиля

stroke-dasharray="4 2"

Мелкий пунктир создаёт ощущение шероховатости при прорисовке.

Технический контур

stroke-dasharray="1 0"

Сплошная линия, максимально чистый эффект рисования.

Грубый набросок

stroke-dasharray="12 6"

Создаёт эффект карандашной штриховки.


Анимация нескольких путей

Если SVG содержит несколько path-элементов, Vivus применяет к каждому:

  • отдельную длину
  • отдельный dashoffset
  • независимую фазу анимации (в зависимости от режима)

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


Группы и вложенные структуры

SVG-элементы внутри <g> ведут себя как контейнеры. Vivus рекурсивно обходит DOM-структуру и применяет анимацию ко всем поддерживаемым элементам.

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

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

Проблемы округления и субпиксели

При работе с dash-offset возможны артефакты:

  • небольшие «дребезги» на концах линий
  • несоответствие начала и конца контура
  • визуальные разрывы на кривых

Причина — дробные значения длины пути и округление в рендерере браузера.


Использование stroke-linecap в связке с Vivus

Тип окончания линии влияет на восприятие анимации:

  • butt — резкое завершение
  • round — мягкое округление
  • square — удлинённый край
stroke-linecap="round"

Округлые окончания визуально сглаживают процесс «дорисовки».


Масштабирование и влияние на dashoffset

При масштабировании SVG через viewBox важно учитывать:

  • длина пути остаётся в исходных координатах
  • визуальное восприятие dashoffset может меняться
  • при динамическом resize требуется переинициализация

Vivus обычно рассчитывает длины один раз, поэтому изменение размеров после инициализации может нарушать синхронизацию.


Анимация сложных логотипов

Логотипы часто состоят из:

  • отдельных букв
  • пересекающихся контуров
  • внутренних вырезов

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

  • сначала внешние формы
  • затем внутренние детали
  • затем декоративные элементы

Комбинирование с CSS-анимациями

Хотя Vivus управляет dashoffset через JavaScript, возможна параллельная работа с CSS:

path {
  transition: stroke 0.3s ease;
}

В таком случае:

  • Vivus отвечает за геометрию появления
  • CSS — за цвет, толщину и визуальные акценты

Поведение при повторном запуске

При повторной инициализации важно учитывать, что:

  • dasharray и dashoffset пересчитываются
  • исходное состояние восстанавливается
  • предыдущая анимация не сохраняется

Это позволяет многократно запускать эффект прорисовки без ручного сброса состояния SVG.


Оптимизация большого количества путей

При большом количестве элементов:

  • вычисление getTotalLength() становится затратным
  • анимация каждого path увеличивает нагрузку на main thread
  • сложные SVG требуют упрощения структуры

Типичная оптимизация:

  • объединение близких контуров
  • упрощение кривых
  • уменьшение количества сегментов path

Визуальные паттерны, основанные на dashoffset

Параметр stroke-dashoffset используется не только для прорисовки, но и для создания динамических эффектов:

  • бесконечное движение контура
  • имитация бегущей линии
  • циклическая анимация границы

Пример циклического смещения:

dashoffset → dashoffset - speed

Связь с восприятием движения

Эффект работы Vivus основан на когнитивной интерпретации:

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

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