etiqueta - animacion svg html5
¿Cómo colocar triángulos de cabeza de flecha en líneas SVG? (1)
Soy nuevo en SVG y estoy tratando de trazar una línea recta entre dos puntos. Logré hasta ahora usando este comando:
<line x1="50" y1="50" x2="150" y2="150" style="stroke:rgb(255,255,0); stroke-width:2" stroke-dasharray="5,3" />"
¿Cuál es la forma más sencilla de agregar triángulos o puntas de flecha diminutas (espaciadas uniformemente) sobre esta línea para indicar la dirección?
Editar 1:
Para ser más claro, no busco una flecha al final de la línea, sino múltiples triángulos (espaciados uniformemente) a lo largo de toda la línea. Si es posible, me gustaría reemplazar cada guión en la línea punteada con un triángulo que apunta en la dirección de la línea.
Editar 2
Según la sugerencia de Phrogz, creé una página como se muestra a continuación, pero no aparece nada. ¿Qué estoy haciendo mal?
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<link href="css/com.css" rel="stylesheet" type="text/css" />
</head>
<body style="background:none;">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 70 90">
<defs>
<marker id="t" markerWidth="4" markerHeight="4"
orient="auto" refY="2">
<path d="M0,0 L4,2 0,4" />
</marker>
</defs>
<polyline points="0,0 0,50 20,70 40,10 42,8 44,10, 46,14 50,50" />
</svg>
<script type="text/javascript">
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;
}
}
</script>
</body>
</html>
En base a una aclaración de la pregunta, aquí hay una implementación de la creación de puntos intermedios a lo largo de un elemento <polyline>
modo que el atributo marker-mid="url(#arrowhead)"
funcionará. Vea a continuación eso para una introducción a 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 elemento <polyline>
existente para agregar puntos a cada unidad de separación a lo largo de cada borde recto. Combine esto con marker-mid
para colocar un marcador girado en cada vértice, y usted tiene la capacidad de dibujar formas / gráficos arbitrariamente complejos de forma constante 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 una "acumulación" antiestética en las esquinas) ya que la demostración anterior muestra que el código no elimina ningún punto que ya tenga en su ruta más cerca que el espaciado valor.
(Sigue la respuesta original de "Introducción a los marcadores").
Desea definir un elemento SVG <marker>
y agregar los atributos marker-start="…"
y / o marker-end="…"
a su línea. El uso de un marcador copia cualquier forma arbitraria en el (los) extremo (s) de su ruta, 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 de arriba:
-
orient="auto"
hace que el marcador gire con la línea -
markerWidth
ymarkerHeight
definen un cuadro delimitador (como un viewBox) para usar para el marcador.- Tenga en cuenta que estos se escalan por el
stroke-width
destroke-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 por el
-
refX
yrefY
definen dónde está el ''origen'' al colocar la forma al final de la ruta- He usado
refX="0.1"
para asegurar que el marcador se superpone 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 está girada).
- Puede ajustar la
fill-opacity
stroke-opacity
del marcador y / o línea de forma independiente, pero los cambios en laopacity
de la línea también afectarán al marcador dibujado.- Como la línea y el marcador se superponen, si reduces la
fill-opacity
defill-opacity
del marcador, verás la superposición; sin embargo, si baja laopacity
de la línea, el marcador se compilará completamente opaco sobre la línea y la combinación de los dos se reducirá en opacidad.
- Como la línea y el marcador se superponen, si reduces la
Si desea flechas a lo largo de la línea, necesitará usar marker-mid="…"
con <path>
o <polyline>
y puntos provisionales 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 desordena la orientación ; Es por eso que en la demostración utilicé una curva de Bézier para doblar la esquina, de modo que el punto medio de la línea esté en 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 hacerlo, puede usar JavaScript y el getPointAtLength()
para una ruta para muestrear la ruta .