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

В библиотеке Snap.svg создание и управление текстовыми элементами реализуется через объект <text>. Для работы с многострочными текстовыми блоками используется элемент <tspan>, позволяющий разбивать текст на строки, задавать отдельные атрибуты и контролировать позиционирование каждой строки.


Создание текста и использование <tspan>

Для начала создается основной элемент текста с помощью метода paper.text(x, y, text). Если требуется многострочный текст, внутри элемента <text> создаются отдельные <tspan> для каждой строки.

var paper = Snap(800, 600);

// Создание основного текстового элемента
var text = paper.text(50, 50, "");

// Добавление многострочных строк
var line1 = paper.tspan("Первая строка").attr({ x: 50, dy: 0 });
var line2 = paper.tspan("Вторая строка").attr({ x: 50, dy: 20 });
var line3 = paper.tspan("Третья строка").attr({ x: 50, dy: 20 });

// Вставка tspan в текстовый элемент
text.add(line1, line2, line3);

Ключевые моменты:

  • x задает горизонтальную позицию строки относительно контейнера <text>.
  • dy задает вертикальное смещение от предыдущей строки. Первой строке обычно присваивается dy: 0.
  • Каждую строку можно стилизовать индивидуально с помощью метода attr.

Индивидуальная стилизация строк

Каждый <tspan> поддерживает все стандартные SVG-атрибуты: fill, font-size, font-family, font-weight, text-anchor.

line1.attr({
    fill: "#ff0000",
    "font-size": 20,
    "font-weight": "bold"
});

line2.attr({
    fill: "#00ff00",
    "font-size": 18,
    "font-style": "italic"
});

line3.attr({
    fill: "#0000ff",
    "font-size": 16
});

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


Автоматический перенос строк

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

function createMultilineText(paper, x, y, text, lineHeight) {
    var lines = text.split("\n");
    var textElement = paper.text(x, y, "");
    
    lines.forEach(function(line, index) {
        var tspan = paper.tspan(line).attr({
            x: x,
            dy: index === 0 ? 0 : lineHeight
        });
        textElement.add(tspan);
    });
    
    return textElement;
}

var multiText = createMultilineText(paper, 50, 100, "Первая строка\nВторая строка\nТретья строка", 25);

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

  • Разделение на строки происходит через символ \n.
  • Параметр lineHeight задает вертикальный интервал между строками.
  • Первый <tspan> всегда имеет dy: 0, остальные смещаются вниз на lineHeight.

Позиционирование многострочного текста

При работе с <tspan> важно учитывать относительные и абсолютные координаты:

  • Атрибут x определяет горизонтальное положение каждой строки. Если x не указан, строка выравнивается по левому краю предыдущей строки.
  • Атрибут dy задает смещение относительно предыдущей строки, а не от верхней границы всего текста.
  • Для выравнивания текста по центру или правому краю используется text-anchor на основном элементе <text> или на отдельном <tspan>.
text.attr({
    "text-anchor": "middle",
    x: 400
});

Анимация текста и <tspan>

Snap.svg позволяет анимировать атрибуты <tspan> независимо. Например, изменение цвета или смещения:

line1.animate({ dy: 30, fill: "#000" }, 1000, mina.easeinout);
line2.animate({ dy: 40, fill: "#333" }, 1200, mina.easeinout);

Таким образом, каждый <tspan> можно анимировать отдельно, создавая динамические многострочные текстовые блоки.


Смешанная графика и текст

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

var path = paper.path("M50,200 C150,100 250,300 350,200");
var textOnPath = paper.text(0, 0, "Текст по кривой");
textOnPath.attr({ "text-anchor": "middle" });
textOnPath.textPath(path);

Советы по работе с <tspan>

  1. Всегда задавать x для каждой строки, чтобы избежать неожиданного смещения.
  2. Использовать dy для точного контроля расстояния между строками.
  3. Разбивать текст программно при необходимости динамического контента.
  4. Комбинировать индивидуальные атрибуты с общими настройками <text> для экономии кода.
  5. Проверять кроссбраузерное отображение, так как рендеринг SVG-текста может отличаться между браузерами.

Эффективное использование <tspan> в Snap.svg позволяет создавать гибкие, многострочные текстовые блоки с полной контролируемостью позиции, стиля и анимации.