Saltar al contenido

¿Cómo colocar triángulos de punta de flecha en líneas SVG?

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.

Pistas de aves

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/

Línea curva con punta de flecha

En lo anterior:

  • orient="auto" hace que el marcador gire con la línea
  • markerWidth y markerHeight 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).
  • refX y refY 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
  • 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 y stroke-opacity del marcador y / o la línea de forma independiente, pero cambia a la opacity 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 el opacity 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.
      ingrese la descripción de la imagen aquí

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/

ingrese la descripción de la imagen aquí

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
ingrese la descripción de la imagen aquí

2. Curva cúbica
ingrese la descripción de la imagen aquí

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>

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *