Многострочный текст

SVG-текст в многорядной структуре в корне отличается от привычной работы с DOM-текстом: браузер отрисовывает <text> и <tspan> как единый объект, но внутри SVG отсутствует привычная блочная модель. При анимации через Vivus это становится критичным, потому что библиотека работает не с текстовыми узлами, а с путями (paths), и каждая строка многострочного текста превращается в набор отдельных геометрических контуров.

SVG не имеет полноценной текстовой верстки уровня HTML. Многострочный текст формируется через:

  • последовательность <tspan>
  • ручное управление координатами x и y
  • либо через разбиение текста на отдельные <text> элементы

Пример структуры:

<text x="0" y="30">
  <tspan x="0" dy="0">Первая строка</tspan>
  <tspan x="0" dy="25">Вторая строка</tspan>
  <tspan x="0" dy="25">Третья строка</tspan>
</text>

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

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

Vivus не работает с текстовыми узлами напрямую. Для анимации многострочного текста используется предварительная конвертация в SVG paths. Это можно сделать несколькими способами:

  • через редакторы векторной графики (Illustrator, Inkscape)
  • через скрипты (например, opentype.js)
  • через серверную генерацию SVG

После конвертации структура выглядит так:

<svg>
  <path d="M10 10 ..."/>
  <path d="M10 40 ..."/>
  <path d="M10 70 ..."/>
</svg>

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

Особенности работы Vivus с многострочными path

Vivus строит анимацию на основе:

  • длины каждого path
  • последовательности отрисовки
  • режима анимации (delayed, sync, oneByOne, script)

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

Ключевой момент: порядок path в DOM определяет порядок появления строк.

Пример поведения:

<svg id="logo">
  <path d="..." />
  <path d="..." />
  <path d="..." />
</svg>

<script>
new Vivus('logo', {
  type: 'oneByOne',
  duration: 120
});
</script>

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

Управление расстоянием между строками после конвертации

После перевода текста в paths теряется семантика строк. Интервал между строками теперь определяется исключительно координатами контуров.

Типичные проблемы:

  • строки «слипаются» при неправильном baseline
  • вертикальные отступы становятся неравномерными
  • масштабирование ломает пропорции межстрочного интервала

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

  • каждая строка размещается в отдельной группе <g>
  • каждая группа смещается по translate(y)
  • внутри группы лежат paths строки

Пример:

<svg id="text">
  <g transform="translate(0, 0)">
    <path d="..." />
  </g>
  <g transform="translate(0, 40)">
    <path d="..." />
  </g>
  <g transform="translate(0, 80)">
    <path d="..." />
  </g>
</svg>

Такой подход сохраняет управляемую структуру многострочного текста.

Анимация каждой строки отдельно

Vivus позволяет управлять порядком отрисовки, но не предоставляет встроенного уровня для строк. Поэтому логика многорядного текста строится через:

  • разбиение SVG на группы
  • последовательную инициализацию Vivus на каждом <g>
  • либо один Vivus-инстанс на весь SVG

При поэтапной анимации:

const blocks = document.querySelectorAll('#text g');

blocks.forEach((block, index) => {
  new Vivus(block, {
    type: 'delayed',
    duration: 80,
    start: 'autostart'
  });
});

Каждая строка начинает анимацию независимо, создавая эффект «печатающегося» многострочного текста.

Синхронизация строк в едином потоке

При необходимости сохранить ощущение единого текста используется режим синхронизации:

  • один Vivus-инстанс
  • общий SVG
  • единый временной поток
new Vivus('text', {
  type: 'sync',
  duration: 200
});

В этом режиме все paths, включая строки текста, анимируются одновременно, но с сохранением их геометрической структуры.

Особенности stroke и заполнения текста

При работе с многострочным текстом в виде paths важно учитывать стили:

  • fill часто отключается для эффекта «рисования»
  • используется только stroke
  • применяются stroke-dasharray и stroke-dashoffset

Типичная конфигурация:

path {
  fill: none;
  stroke: #000;
  stroke-width: 2;
}

После завершения анимации часто выполняется переключение:

  • stroke → fill
  • или добавление opacity transition

Проблемы масштабирования многострочного SVG

SVG с текстом, преобразованным в paths, теряет текстовую адаптивность. При изменении размера:

  • расстояния между строками могут искажаться
  • пропорции букв нарушаются
  • анимация может начинаться не с ожидаемой точки

Решение заключается в использовании:

  • viewBox
  • фиксированных координат
  • отказа от абсолютных px в пользу относительных единиц внутри SVG

Пример:

<svg viewBox="0 0 300 150">

Это позволяет сохранять структуру многострочного текста независимо от контейнера.

Разделение длинных текстовых блоков на логические сегменты

При сложных композициях многострочный текст делится на смысловые блоки:

  • заголовок
  • подзаголовок
  • основной текст
  • акцентные строки

Каждый блок становится отдельной группой SVG:

<g id="title"></g>
<g id="subtitle"></g>
<g id="body"></g>

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

Задержки и каскадная анимация строк

Один из наиболее выразительных эффектов при работе с Vivus — каскадное появление строк.

Реализуется через:

  • разные delay для каждого Vivus-инстанса
  • или модификацию pathTimingFunction

Пример каскада:

blocks.forEach((block, i) => {
  setTimeout(() => {
    new Vivus(block, {
      type: 'oneByOne',
      duration: 100
    });
  }, i * 300);
});

Такой подход создаёт эффект постепенного «раскрытия» текста построчно.

Технические ограничения при работе с текстом

При использовании многострочного текста в Vivus важно учитывать ограничения:

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

Поэтому оптимизация часто включает:

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

Взаимодействие многострочного текста с масками

Расширенные визуальные эффекты строятся через SVG masks:

  • текст становится маской
  • поверх накладывается анимируемый слой
  • Vivus управляет только контуром

Пример логики:

  • paths текста → mask
  • прямоугольник с градиентом → animated layer

Это позволяет создавать эффект «проявляющегося текста» построчно.

Архитектурный подход к многострочным SVG-анимациям

При построении сложных интерфейсов с Vivus многострочный текст рассматривается как система:

  • геометрия (paths)
  • структура (groups)
  • анимационный слой (Vivus instances)
  • тайминг (JS scheduler)

Такой подход позволяет масштабировать:

  • от одиночных заголовков
  • до целых анимированных текстовых экранов