Текст вдоль пути (textPath)

Snap.svg предоставляет удобный и гибкий механизм для отображения текста вдоль кривых и сложных контуров с использованием элемента <textPath> SVG. Этот подход позволяет визуально оживлять графику и создавать эффекты, недоступные при стандартном позиционировании текста.

Основы работы с <textPath>

Элемент <textPath> используется внутри <text> и привязывается к определённому <path> через атрибут href. В Snap.svg это реализуется через объект Snap.Path и метод text, а текст размещается с помощью метода textPath.

Пример создания базового текста вдоль линии:

var s = Snap(800, 200); // Создание холста
var path = s.path("M50,150 C150,50 350,250 450,150"); // Кривая Безье
var text = s.text(0, 0, "Текст вдоль кривой");
text.attr({ "font-size": 24, fill: "#000" });

var textPath = text.textPath(path); // Привязка текста к пути

В данном примере текст следует по кривой, определённой линией Безье. Snap.svg автоматически преобразует координаты текста, чтобы он повторял форму пути.

Атрибуты и настройка поведения текста

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

textPath.attr({ startOffset: "50%" }); // Текст центрируется по середине пути

2. textLength и lengthAdjust Позволяют контролировать растяжение текста вдоль пути. textLength задаёт длину текста, а lengthAdjust определяет способ масштабирования (spacing или spacingAndGlyphs):

textPath.attr({ textLength: 400, lengthAdjust: "spacingAndGlyphs" });

3. side Snap.svg позволяет указать сторону текста относительно пути (left, right, center). В стандартном SVG это регулируется через атрибут dominant-baseline и text-anchor. В Snap.svg часто используется комбинация этих атрибутов:

text.attr({
    "text-anchor": "middle",  // Центрирование текста относительно точки startOffset
    "dominant-baseline": "middle"
});

Работа с кривыми сложной формы

Для кривых, которые содержат резкие изгибы, важно учитывать оригинальное направление пути. Текст всегда следует по направлению определения path (MLC), поэтому для зеркальных или обратных эффектов можно использовать метод transform:

path.transform("scale(-1,1) translate(-500,0)"); // Инвертирование пути по оси X

Многострочный текст вдоль пути

В стандартном SVG <textPath> не поддерживает разбиение на строки, однако Snap.svg позволяет эмулировать многострочность через создание нескольких <text> элементов, каждый из которых привязывается к смещённому пути:

var lines = ["Первая строка", "Вторая строка", "Третья строка"];
lines.forEach(function(line, i){
    var t = s.text(0, 0, line).attr({ "font-size": 20 });
    t.textPath(path).attr({ startOffset: i * 25 });
});

Здесь каждая строка сдвигается вдоль пути за счёт увеличения startOffset, создавая эффект нескольких линий текста по одной кривой.

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

Snap.svg позволяет плавно перемещать текст по кривой с помощью анимаций атрибута startOffset:

textPath.attr({ startOffset: "0%" })
    .animate({ startOffset: "100%" }, 3000, mina.linear);

Это позволяет создавать динамичные эффекты движения текста, например, бегущую строку или имитацию движения объекта вдоль трассы.

Комбинирование с другими эффектами

Текст вдоль пути легко интегрировать с другими возможностями Snap.svg:

  • Градиенты и паттерны: можно задавать fill с градиентом, чтобы текст менял цвет по длине кривой.
  • События и интерактивность: текст остаётся SVG-элементом, поэтому можно привязывать события click, mouseover и т.д.
  • Трансформации: можно вращать, масштабировать или наклонять текст без изменения пути.
textPath.attr({
    fill: s.gradient("r(0.5, 0.5, 0.5)#f00-#00f")
});
textPath.hover(
    function(){ this.attr({ fill: "#0f0" }); },
    function(){ this.attr({ fill: "#f00" }); }
);

Оптимизация и рекомендации

  • Использовать простые пути для длинного текста, чтобы избежать накладных вычислений и замедления рендеринга.
  • Проверять ориентацию пути для корректного отображения текста: направление кривой напрямую влияет на изгиб текста.
  • Для анимации больших объёмов текста лучше использовать атрибут startOffset вместо постоянного пересоздания элементов, что снижает нагрузку на DOM.

Snap.svg делает работу с текстом вдоль кривых интуитивной, позволяя комбинировать возможности SVG с удобными методами библиотеки для управления атрибутами, анимацией и интерактивностью.