Рисуем стрелки при помощи Marker

Для создания диаграмм и графиков часто требуются стрелки. Вы можете их задать при помощи элемента marker, которые нужно разместить внутри секции defs. Стрелки применимы к line, polyline, polygon и path.


<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 100" width="350" height="100">
  <defs>
    <marker id="arrowhead" markerWidth="10" markerHeight="7" 
    refX="0" refY="3.5" orient="auto">
      <polygon points="0 0, 10 3.5, 0 7" />
    </marker>
  </defs>
  <line x1="0" y1="50" x2="250" y2="50" stroke="#000" 
  stroke-width="8" marker-end="url(#arrowhead)" />
</svg>

Размеры наконечника заданы через markerWidth и markerHeight. Фигура образует треугольник, направление задано в line через marker-end через идентификатор стрелки.

Атрибуты refX и refY задают позицию стрелки относительно конца пути. Устанавливая эти значения в 0 (по умолчанию), мы размещаем верхний левый угол marker в конец линии. Для создания нормальной стрелки нужно установить значение 0 для позиции X и половину высоты стрелки в позиции Y.

Установка у атрибута orient значения auto выравнивает стрелку в пути. Это удобно, если стрелка будет наклонной.


<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 100" width="350" height="100">
  <defs>
    <marker id="arrowhead" markerWidth="10" markerHeight="7" 
    refX="0" refY="3.5" orient="auto">
      <polygon points="0 0, 10 3.5, 0 7" />
    </marker>
  </defs>
  <line x1="3" y1="4" x2="250" y2="50" 
	stroke="#000" stroke-width="8" 
	marker-end="url(#arrowhead)" />
</svg>

В большинстве случае автоматическое выравнивание можно оставить. Но если вам нужно изменить это поведение, то можете указать точный угол поворота.


orient="35"

Двойные стрелки

Создав элемент marker мы можем использовать его несколько раз. Например, создадим стрелку с оперением, разместив элемент вначале и в конце линии. Это один и тот же marker, но указаны разные позиции.


<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 100" width="350" height="100">
  <defs>
    <marker id="arrowhead" markerWidth="10" markerHeight="7" 
	refX="0" refY="3.5" orient="auto">
      <polygon points="0 0, 10 3.5, 0 7" />
    </marker>
  </defs>
  <line x1="0" y1="50" x2="250" y2="50" stroke="#000" stroke-width="8" 
	marker-end="url(#arrowhead)" marker-start="url(#arrowhead)" />
</svg>

Ничто не мешает создать независимые стрелки с разными идентификаторами.


<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 100" width="350" height="100">
  <defs>
    <marker id="startarrow" markerWidth="10" markerHeight="7" 
    refX="10" refY="3.5" orient="auto">
      <polygon points="10 0, 10 7, 0 3.5" fill="royalblue" />
    </marker>
    <marker id="endarrow" markerWidth="10" markerHeight="7" 
    refX="0" refY="3.5" orient="auto" markerUnits="strokeWidth">
        <polygon points="0 0, 10 3.5, 0 7" fill="tomato" />
    </marker>
  </defs>
  <line x1="100" y1="50" x2="250" y2="50" stroke="#000" stroke-width="8" 
  marker-end="url(#endarrow)" marker-start="url(#startarrow)" />
</svg>

Для примера пришлось укоротить линию, чтобы добавить первую стрелку. А также для неё изменили refX.

Ещё один пример. Здесь встречаются такие элементы как vector-effect, markerUnits.


<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 200" width="300" height="200">
  <defs>
    <style>
        path, polyline {
            fill: none;
            stroke: #231F20;
            vector-effect: non-scaling-stroke;
            stroke-width: 2;
       }
        path {
            stroke-dasharray: 11, 5; 
        }
    </style>
    <marker id="pointer" markerWidth="10" markerHeight="8" 
	refX="9.5" refY="5.1" orient="-45" markerUnits="userSpaceOnUse">
        <polyline points="1 1, 9 5, 1 7" />
    </marker>
  </defs>
  <path d="M16.7,178 c87.6-46.9,162.9-185.4,227-136.4C307.2,90.1,195,158.5,111,108.9C71,85.2,92.2,30.7,126,7" 
    marker-end="url(#pointer)"/>
</svg>

В векторных редакторах могут быть проблемы с поддержкой стрелок.

Источник: the new code – Making Arrows in SVG

Вернуться в раздел SVG

Реклама