Ответ 1
Основываясь на пояснении вопроса, здесь реализована реализация создания промежуточных точек вдоль элемента <polyline>
, так что атрибут marker-mid="url(#arrowhead)"
будет работать. См. Ниже, что для введения в маркеры и стрелки.
Демо: http://jsfiddle.net/Zv57N/
midMarkers(document.querySelector('polyline'),6);
// Given a polygon/polyline, create intermediary points along the
// "straightaways" spaced no closer than `spacing` distance apart.
// Intermediary points along each section are always evenly spaced.
// Modifies the polygon/polyline in place.
function midMarkers(poly,spacing){
var svg = poly.ownerSVGElement;
for (var pts=poly.points,i=1;i<pts.numberOfItems;++i){
var p0=pts.getItem(i-1), p1=pts.getItem(i);
var dx=p1.x-p0.x, dy=p1.y-p0.y;
var d = Math.sqrt(dx*dx+dy*dy);
var numPoints = Math.floor( d/spacing );
dx /= numPoints;
dy /= numPoints;
for (var j=numPoints-1;j>0;--j){
var pt = svg.createSVGPoint();
pt.x = p0.x+dx*j;
pt.y = p0.y+dy*j;
pts.insertItemBefore(pt,i);
}
if (numPoints>0) i += numPoints-1;
}
}
Вышеупомянутый код изменяет существующий элемент <polyline>
, чтобы добавить точки на каждый промежуточный блок вдоль каждого прямого края. Объедините это с marker-mid
, чтобы поместить повернутый маркер в каждую вершину, и у вас есть возможность последовательно рисовать произвольно сложные фигуры/графику вдоль вашего пути.
Хотя код помещает точки равномерно вдоль каждого сегмента (так что в углах не возникает неприглядная "группировка" ), поскольку приведенная выше демонстрация показывает, что код не удаляет точки, которые у вас уже есть на вашем пути, которые ближе друг к другу чем значение расстояния.
(Далее следует ответ "Вступление к маркерам" ).
Вы хотите определить элемент SVG <marker>
и добавить в свою строку атрибуты marker-start="…"
и/или marker-end="…"
. Использование маркера копирует любую произвольную фигуру на конец вашего пути и (с помощью orient="auto"
) вращает форму, чтобы она соответствовала.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50 -100 200 200">
<defs>
<marker id='head' orient='auto' markerWidth='2' markerHeight='4'
refX='0.1' refY='2'>
<path d='M0,0 V4 L2,2 Z' fill='red' />
</marker>
</defs>
<path
marker-end='url(#head)'
stroke-width='5' fill='none' stroke='black'
d='M0,0 C45,45 45,-45 90,0'
/>
</svg>
Демо: http://jsfiddle.net/Z5Qkf/1/
В приведенном выше примере:
-
orient="auto"
заставляет маркер вращаться с линией -
markerWidth
иmarkerHeight
определяют ограничивающий прямоугольник (например, viewBox) для использования для маркера.- Обратите внимание, что они затем масштабируются с помощью
stroke-width
конечной строки; имеющий высоту "4", в конечном чертеже он составляет 20 единиц ширины (4 и 5 раз).
- Обратите внимание, что они затем масштабируются с помощью
-
refX
иrefY
определить, где "происхождение" находится при размещении фигуры в конце пути- Я использовал
refX="0.1"
, чтобы убедиться, что маркер частично перекрывает конец строки.
- Я использовал
- Для правильной работы автоматической ориентации вы хотите, чтобы направление "вперед" маркера находилось в направлении + x. (Красный путь, используемый для маркера, выглядит следующим образом: ▶ при отключении.)
- Вы можете отрегулировать
fill-opacity
иstroke-opacity
маркера и/или строки независимо, но изменения в строкеopacity
будут влиять на рисованный маркер.- Так как линия и маркер перекрываются, если вы опустите
fill-opacity
маркера, вы увидите перекрытие; однако, если вы опуститеopacity
самой линии, тогда маркер будет скомпонован полностью непрозрачным по линии, а затем комбинация этих двух будет уменьшена в непрозрачности.
- Так как линия и маркер перекрываются, если вы опустите
Если вам нужны стрелки вдоль длины строки, вам нужно будет использовать marker-mid="…"
с помощью <path>
или <polyline>
и промежуточных точек вдоль линии.
Демо: http://jsfiddle.net/Z5Qkf/2/
Единственная проблема заключается в том, что любая точка, меняющая направление вдоль линии испортила ориентацию; поэтому в демо я использовал кривую Безье, чтобы обогнуть угол, так что средняя точка на линии находится вдоль прямой секции.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-50 -100 200 200">
<defs>
<marker id='mid' orient="auto"
markerWidth='2' markerHeight='4'
refX='0.1' refY='1'>
<!-- triangle pointing right (+x) -->
<path d='M0,0 V2 L1,1 Z' fill="orange"/>
</marker>
<marker id='head' orient="auto"
markerWidth='2' markerHeight='4'
refX='0.1' refY='2'>
<!-- triangle pointing right (+x) -->
<path d='M0,0 V4 L2,2 Z' fill="red"/>
</marker>
</defs>
<path
id='arrow-line'
marker-mid='url(#mid)'
marker-end='url(#head)'
stroke-width='5'
fill='none' stroke='black'
d='M0,0 L20,20 C40,40 40,40 60,20 L80,0'
/>
</svg>
Чтобы сделать это процедурно, вы можете использовать JavaScript и команду getPointAtLength()
для пути к пример пути.