Измерение текста

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

Создание текстового элемента

var s = Snap(800, 600);
var text = s.text(0, 0, "Пример текста");

Метод text(x, y, content) создает SVG-элемент <text> по координатам (x, y) с содержимым content. Элемент можно перемещать, масштабировать, стилизовать и измерять его свойства.

Определение размеров текста

Для измерения текста используется метод getBBox(). Этот метод возвращает объект с границами ограничивающего прямоугольника элемента:

var bbox = text.getBBox();
console.log(bbox.x, bbox.y, bbox.width, bbox.height);

Параметры объекта bbox:

  • x – координата верхнего левого угла по оси X
  • y – координата верхнего левого угла по оси Y
  • width – ширина текста
  • height – высота текста
  • cx – центр по оси X (x + width / 2)
  • cy – центр по оси Y (y + height / 2)

Метод getBBox() учитывает текущие трансформации (transform) и стили, влияющие на размер, включая font-size, font-family, font-weight и line-height.

Учет стилей при измерении

Чтобы получить точные размеры текста, нужно применять стили перед вызовом getBBox():

text.attr({
    'font-size': 24,
    'font-family': 'Arial',
    'font-weight': 'bold'
});

var bboxStyled = text.getBBox();
console.log(bboxStyled.width, bboxStyled.height);

Без указания стилей размеры будут вычислены на основе наследуемых или дефолтных параметров SVG, что может привести к неточностям.

Динамическое измерение текста

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

text.attr({ text: "Новый текст" });
var newBbox = text.getBBox();

Использование getBBox() гарантирует, что будут учтены новая длина строки и высота шрифта.

Высота шрифта и межстрочный интервал

Snap.svg напрямую не предоставляет метод для вычисления точного межстрочного интервала (line-height). Можно приблизительно вычислить высоту строки через getBBox().height и делить её на количество строк, если используется многострочный <tspan>:

var multiLine = s.text(0, 0, ["Первая строка", "Вторая строка"]);
var bboxMulti = multiLine.getBBox();
var lineHeight = bboxMulti.height / 2;

Для точного контроля над многострочным текстом рекомендуется создавать отдельные <tspan> для каждой строки с индивидуальной позицией dy.

Измерение ширины текста без добавления на холст

Иногда требуется узнать ширину текста до его визуального размещения. В Snap.svg нет нативного метода для «невидимого» измерения, но можно создать временный элемент с нулевой видимостью:

var temp = s.text(0, 0, "Тест").attr({ visibility: "hidden" });
var tempBbox = temp.getBBox();
temp.remove();
console.log(tempBbox.width);

Такой подход позволяет измерять размеры текста без влияния на пользовательский интерфейс.

Учет трансформаций

Если текст подвергнут масштабированию, повороту или сдвигу, getBBox() возвращает координаты уже с учетом этих трансформаций:

text.transform("s2"); // масштаб 2x
var transformedBbox = text.getBBox();
console.log(transformedBbox.width); // ширина удвоена

Для измерений без учета трансформаций можно использовать getBBox({stroke:true}) или сохранить исходные атрибуты перед преобразованием.

Практические рекомендации

  • Всегда применять необходимые стили до измерения текста, чтобы избежать неправильных размеров.
  • Для динамического контента пересчитывать getBBox() каждый раз после изменения текста.
  • Для многострочного текста использовать <tspan> для контроля вертикального позиционирования.
  • Если требуется измерение без отображения, использовать временный скрытый элемент.

Использование этих методов позволяет создавать точные и адаптивные интерфейсы на основе SVG, корректно размещать текст и выравнивать элементы по центру или по границам текста.