Ориентация маркеров

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

Создание маркеров

Маркер создается как отдельный SVG-элемент <marker> с уникальным идентификатором:

var s = Snap("#svg");
var marker = s.marker(0, 0, 10, 10, 5, 5);
marker.path("M0,0 L10,5 L0,10 Z").attr({
    fill: "#f00"
});

Параметры метода s.marker:

  • x, y – координаты начальной точки маркера.
  • width, height – размеры области маркера.
  • refX, refY – точка привязки маркера к линии.

Привязка маркера к линии

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

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

Snap.svg автоматически вставляет ссылку на маркер через url(#id), если маркер был создан через метод s.marker.

Управление ориентацией маркера

Ключевой момент – автоматическая ориентация маркера вдоль линии. По умолчанию, маркер ориентируется по касательной к сегменту линии:

  • orient="auto" – Snap.svg устанавливает направление вдоль пути.
  • orient="0" или любое числовое значение в градусах – фиксированное направление маркера.

Пример с автоматической ориентацией:

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

Несколько маркеров на одном пути

Можно использовать разные маркеры на начале, середине и конце линии:

var midMarker = s.marker(0,0,6,6,3,3);
midMarker.path("M0,0 L6,3 L0,6 Z").attr({fill: "#00f"});

line.attr({
    "marker-start": marker,
    "marker-mid": midMarker,
    "marker-end": marker
});

Маркер на середине (marker-mid) повторяется на всех узлах пути между сегментами.

Динамическая ориентация при изменении пути

Если путь изменяется программно, Snap.svg корректно перенастраивает ориентацию маркера:

line.animate({ x2: 300, y2: 100 }, 1000);

Благодаря orient="auto", стрелка плавно поворачивается в новом направлении линии без дополнительного кода.

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

Snap.svg позволяет использовать любые формы как маркеры:

var squareMarker = s.marker(0, 0, 8, 8, 4, 4);
squareMarker.rect(0, 0, 8, 8).attr({fill: "#0f0"});

line.attr({"marker-end": squareMarker});

Форма не влияет на ориентацию, если задан orient="auto". Snap.svg поворачивает маркер по касательной линии к последнему сегменту.

Применение к кривым и сложным путям

Для кривых (path) маркеры работают так же, как для прямых линий. При этом Snap.svg учитывает направление кривой в точке привязки:

var path = s.path("M50,150 C150,50 250,250 350,150");
path.attr({
    stroke: "#000",
    strokeWidth: 3,
    fill: "none",
    "marker-end": marker
});

Маркер поворачивается по касательной кривой в конце пути, обеспечивая правильное визуальное направление.

Стилизация маркеров

Маркер наследует базовые SVG-атрибуты: fill, stroke, stroke-width. Для динамического изменения цвета или размера:

marker.attr({
    fill: "#ff0",
    stroke: "#000",
    strokeWidth: 1
});

Особенности работы с transform

Маркер привязывается к локальной системе координат линии. Если к линии применяется трансформация (transform), Snap.svg корректно поворачивает маркер:

line.transform("rotate(45, 50, 50)");

Маркер сохраняет ориентацию по линии после трансформации, если используется orient="auto".

Итоговые рекомендации

  • Для динамических линий всегда использовать orient="auto".
  • Разные маркеры можно комбинировать на одной линии через marker-start, marker-mid, marker-end.
  • Snap.svg поддерживает любые формы маркеров: стрелки, квадраты, круги.
  • Любые изменения пути автоматически корректируют ориентацию маркера без дополнительного кода.

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