В библиотеке Snap.svg текстовые элементы создаются с помощью метода
paper.text(x, y, content), где x и
y задают координаты начала текста, а content —
строковое значение. Однако сам по себе объект text не имеет
понятия границ, что делает невозможным прямое управление размерами
блока. Для реализации границ текстового блока
необходимо использовать комбинацию текстового элемента и прямоугольника
(rect), синхронизируя их размеры и позицию.
Snap.svg предоставляет метод getBBox(), который
возвращает объект с координатами и размерами элемента. Пример:
var paper = Snap(800, 600);
var text = paper.text(50, 50, "Пример текста для блока");
var bbox = text.getBBox();
console.log(bbox);
// {x: 50, y: 50, width: ..., height: ..., cx: ..., cy: ...}
Пояснения к свойствам:
x и y — координаты верхнего левого угла
прямоугольника, окружающего текст.width и height — размеры, которые
фактически занимает текст.cx и cy — координаты центра элемента.Использование getBBox() позволяет динамически
адаптировать границу под размер текста.
Для визуализации границы текстового блока создается элемент
rect с размерами, полученными из
getBBox():
var padding = 10; // Отступы вокруг текста
var rect = paper.rect(
bbox.x - padding,
bbox.y - padding,
bbox.width + 2 * padding,
bbox.height + 2 * padding
);
rect.attr({
fill: "none",
stroke: "#000",
strokeWidth: 2
});
Особенности:
padding добавляет пространство вокруг текста, чтобы
граница не слипалась с символами.fill: "none" делает прямоугольник прозрачным внутри,
оставляя только рамку.stroke и strokeWidth позволяют настроить
цвет и толщину линии границы.Чтобы текст был строго внутри границы и был выровнен по центру, нужно
корректировать координаты x и y с учетом
размеров прямоугольника:
var textX = rect.attr("x") + rect.attr("width") / 2;
var textY = rect.attr("y") + rect.attr("height") / 2;
text.attr({
x: textX,
y: textY,
textAnchor: "middle",
alignmentBaseline: "middle"
});
textAnchor: "middle" выравнивает текст по горизонтали
по центру.alignmentBaseline: "middle" обеспечивает вертикальное
центрирование.Чтобы граница корректировалась при изменении содержимого текста,
применяется пересчет getBBox():
function updateTextBlock(textElement, rectElement, padding) {
var bbox = textElement.getBBox();
rectElement.attr({
x: bbox.x - padding,
y: bbox.y - padding,
width: bbox.width + 2 * padding,
height: bbox.height + 2 * padding
});
textElement.attr({
x: bbox.cx,
y: bbox.cy,
textAnchor: "middle",
alignmentBaseline: "middle"
});
}
Использование функции updateTextBlock позволяет
динамически управлять текстовыми блоками в интерфейсе, включая
добавление текста, смену шрифта или размера.
Snap.svg не поддерживает нативные многострочные элементы
<tspan> с автоматическим переносом, поэтому
необходимо вручную создавать строки:
var lines = ["Первая строка", "Вторая строка", "Третья"];
var yStart = 50;
var lineHeight = 20;
var textGroup = paper.group();
lines.forEach((line, index) => {
var t = paper.text(50, yStart + index * lineHeight, line);
textGroup.add(t);
});
var bboxGroup = textGroup.getBBox();
var rect = paper.rect(
bboxGroup.x - padding,
bboxGroup.y - padding,
bboxGroup.width + 2 * padding,
bboxGroup.height + 2 * padding
);
rect.attr({ fill: "none", stroke: "#333", strokeWidth: 2 });
group), что позволяет
получить общий getBBox().Snap.svg поддерживает работу с атрибутами SVG, что позволяет создавать не только прямые линии, но и закругленные углы и пунктирные рамки:
rect.attr({
rx: 10, // закругление углов по горизонтали
ry: 10, // закругление углов по вертикали
strokeDasharray: "5,5" // пунктирная линия
});
Используемые эффекты:
rx и ry — создают плавное скругление
углов.strokeDasharray — задает стиль линии (сплошная,
пунктирная, штрих-пунктир).strokeOpacity и fillOpacity позволяют
изменять прозрачность границы и фона.Snap.svg позволяет анимировать размер и цвет рамки, что полезно для интерактивных интерфейсов:
rect.animate({ width: bbox.width + 50, height: bbox.height + 50 }, 500, mina.easeinout);
rect.animate({ stroke: "#ff0000" }, 300);
animate принимает объект свойств, длительность анимации
и функцию easing.Обобщённая структура для текстового блока с границей в Snap.svg:
getBBox() для размеров.padding.updateTextBlock.Такой подход обеспечивает гибкое управление визуальными текстовыми блоками, полностью контролируемыми через Snap.svg, с возможностью расширения до интерактивных интерфейсов и сложной визуализации.