Solución:
Basado en una aclaración de la pregunta, aquí hay una implementación de la creación de puntos intermedios a lo largo de un <polyline>
elemento tal que el marker-mid="url(#arrowhead)"
El atributo funcionará. Vea a continuación eso para una introducción a los marcadores y puntas de flecha.
Demostración: 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;
}
}
El código anterior modifica un existente <polyline>
elemento para sumar puntos cada espaciado unidades a lo largo de cada regla. Combine esto con marker-mid
para colocar un marcador girado en cada vértice, y tiene la capacidad de dibujar formas / gráficos arbitrariamente complejos de manera consistente a lo largo de su camino.
Aunque el código separa los puntos de manera uniforme a lo largo de cada segmento (para que no se produzca un “ agrupamiento ” antiestético en las esquinas), como muestra la demostración anterior, el código no elimina ningún punto que ya tenga en su camino que esté más cerca que el espaciado valor.
(A continuación, se muestra la respuesta original de “Introducción a los marcadores”).
Quieres definir un SVG <marker>
elemento y agregue el marker-start="…"
y / o marker-end="…"
atributos a su línea. El uso de un marcador copia cualquier forma arbitraria en el (los) final (es) de su camino, y (con orient="auto"
) gira la forma para que coincida.
<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>
Demostración: http://jsfiddle.net/Z5Qkf/1/
En lo anterior:
-
orient="auto"
hace que el marcador gire con la línea -
markerWidth
ymarkerHeight
definir un cuadro delimitador (como un viewBox) para usar como marcador.- Tenga en cuenta que estos se escalan luego por el
stroke-width
de la línea final; tener una altura de “4” hace que tenga 20 unidades de ancho en el dibujo final (4 × 5).
- Tenga en cuenta que estos se escalan luego por el
-
refX
yrefY
definir dónde está el ‘origen’ al colocar la forma al final de la ruta- he usado
refX="0.1"
para asegurarse de que el marcador se superponga ligeramente al final de la línea
- he usado
- Para que la orientación automática funcione correctamente, desea que la dirección “hacia adelante” del marcador esté en la dirección + x. (La ruta roja utilizada para el marcador se ve así ▶ cuando no se gira).
- Puede ajustar el
fill-opacity
ystroke-opacity
del marcador y / o la línea de forma independiente, pero cambia a laopacity
de la línea afectará también al marcador dibujado.-
Dado que la línea y el marcador se superponen, si baja el
fill-opacity
del marcador verá la superposición; sin embargo, si baja elopacity
de la línea en sí, el marcador se compone completamente opaco sobre la línea y la combinación de los dos se reduce en opacidad.
-
Dado que la línea y el marcador se superponen, si baja el
Si desea flechas a lo largo de la línea, deberá usar marker-mid="…"
con cualquiera <path>
o <polyline>
y puntos intermedios a lo largo de la línea.
Demostración: http://jsfiddle.net/Z5Qkf/2/
El único problema es que cualquier punto que cambie de dirección a lo largo de la línea estropea la orientación; es por eso que en la demostración utilicé una curva de Bézier para redondear la esquina de modo que el punto medio de la línea esté a lo largo de una sección recta.
<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>
Para hacer esto de manera procedimental, puede usar JavaScript y el getPointAtLength()
comando para una ruta para muestrear la ruta.
Solo quiero agregar algunos enlaces y ejemplos útiles:
1. La flecha puede ser cuadrática
2. Curva cúbica
Documentación: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
Manifestación: ambos tipos de flechas implementadas aquí:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<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'>
<!-- triangle pointing right (+x) -->
<path d='M0,0 V4 L2,2 Z' fill="black"/>
</marker>
</defs>
<path
id='arrow-line'
marker-end='url(#head)'
stroke-width="1"
fill="none" stroke="black"
d='M0,0 Q45,-20 90,0'
/>
<path
id='arrow-line'
marker-end='url(#head)'
stroke-width="1"
fill="none" stroke="black"
d='M0,50 C10,30 80,30 90,50'
/>
</svg>
</body>
</html>