Стрелки на концах линий

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


Определение маркера

Маркер создается через метод paper.marker(width, height, refX, refY, viewBoxX, viewBoxY, vbWidth, vbHeight), где:

  • width и height – размеры маркера в пикселях.
  • refX и refY – координаты точки, к которой будет “прикрепляться” линия.
  • viewBoxX, viewBoxY, vbWidth, vbHeight – параметры viewBox для масштабирования содержимого маркера.

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

var paper = Snap(800, 600);

var arrowMarker = paper.marker(10, 10, 5, 5, 0, 0, 10, 10);
arrowMarker.add(paper.path("M0,0 L10,5 L0,10 L2,5 Z").attr({
    fill: "#000"
}));

Здесь:

  • M0,0 L10,5 L0,10 L2,5 Z — путь, формирующий треугольную стрелку.
  • Атрибут fill задает цвет заливки стрелки.

Применение маркера к линии

После создания маркера его можно применить к линии или любому элементу пути с помощью атрибутов marker-start, marker-mid, marker-end:

var line = paper.line(50, 50, 300, 200);
line.attr({
    stroke: "#000",
    strokeWidth: 2,
    'marker-end': arrowMarker
});

Здесь стрелка будет отображаться на конце линии. Для отображения стрелки в начале линии используется marker-start, а для промежуточных точек — marker-mid.


Настройка ориентации стрелки

По умолчанию маркер ориентируется вдоль линии автоматически. Это задается атрибутом orient="auto":

arrowMarker.attr({
    orient: "auto"
});

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


Использование маркеров на кривых и сложных путях

Маркер можно применять не только к прямым линиям, но и к любым SVG-путям:

var path = paper.path("M50,50 C150,100 200,150 300,200");
path.attr({
    stroke: "#f00",
    strokeWidth: 3,
    fill: "none",
    'marker-end': arrowMarker
});

Кривые будут автоматически корректно отображать стрелку на конце благодаря orient="auto".


Масштабирование и позиционирование маркера

Чтобы изменить размер стрелки относительно толщины линии, можно использовать атрибут markerUnits="strokeWidth":

arrowMarker.attr({
    markerUnits: "strokeWidth"
});

Это гарантирует, что стрелка будет масштабироваться пропорционально толщине линии, сохраняя визуальную гармонию.


Цвет и стилизация стрелок

Стрелки наследуют стили от самого пути только при использовании stroke. Для отдельной заливки можно задавать fill непосредственно внутри маркера. Также поддерживаются градиенты, прозрачность и другие SVG-стили:

arrowMarker.add(paper.path("M0,0 L10,5 L0,10 L2,5 Z").attr({
    fill: "url(#grad1)",
    stroke: "#333",
    strokeWidth: 0.5
}));

Комбинирование стрелок на обоих концах

Можно одновременно добавить маркеры на начало и конец линии:

line.attr({
    'marker-start': arrowMarker,
    'marker-end': arrowMarker
});

Для визуального разнообразия можно создавать отдельные маркеры для начала и конца, с разными формами или цветами.


Динамическое обновление стрелок

В Snap.svg элементы можно обновлять в любое время. Изменение маркера линии производится простым присвоением нового маркера:

var newArrow = paper.marker(15, 15, 7, 7, 0, 0, 15, 15);
newArrow.add(paper.path("M0,0 L15,7.5 L0,15 L3,7.5 Z").attr({fill: "#00f"}));

line.attr({
    'marker-end': newArrow
});

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


Заключение по применению маркеров

Маркер в Snap.svg — это мощный инструмент для визуализации направлений и потоков на схемах и графиках. Использование marker-start, marker-mid и marker-end в сочетании с гибкой настройкой viewBox, orient и markerUnits позволяет создавать стрелки любой формы, размера и ориентации, полностью интегрированные с линиями и кривыми SVG.

Это обеспечивает высокую визуальную точность и масштабируемость графики, что особенно важно при построении сложных диаграмм, сетей и схем взаимодействий.