Je suis nouveau sur SVG et j'essaie de tracer une ligne droite entre deux points. J'ai réussi jusqu'à présent en utilisant cette commande:
<line x1="50" y1="50" x2="150" y2="150" style="stroke:rgb(255,255,0); stroke-width:2" stroke-dasharray="5,3" />"
Quelle est la manière la plus simple d'ajouter de minuscules triangles ou têtes de flèche (régulièrement espacés) sur cette ligne afin d'indiquer la direction?
Modifier 1:
Pour être plus clair, je ne suis pas après une flèche à la fin de la ligne, mais plusieurs triangles (régulièrement espacés) sur toute la ligne. Si possible, je voudrais remplacer chaque tiret de la ligne pointillée par un triangle pointant dans la direction de la ligne.
Éditer 2
Sur la base de la suggestion de Phrogz, j'ai créé une page comme indiqué ci-dessous, mais rien ne s'affiche. Qu'est-ce que je fais 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>
Sur la base d'une clarification de la question, voici une implémentation de la création de points intermédiaires le long d'un élément <polyline>
De telle sorte que l'attribut marker-mid="url(#arrowhead)"
fonctionnera. Voir ci-dessous pour une introduction aux marqueurs et pointes de flèches.
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;
}
}
Le code ci-dessus modifie un élément <polyline>
Existant pour ajouter des points toutes les unités d'espacement le long de chaque arête droite. Combinez cela avec marker-mid
Pour placer un marqueur pivoté à chaque sommet, et vous avez la possibilité de dessiner des formes/graphiques arbitrairement complexes de manière cohérente le long de votre chemin.
Bien que le code espace les points uniformément le long de chaque segment (de sorte qu'aucun `` regroupement '' disgracieux ne se produise dans les coins), comme le montre la démonstration ci-dessus, le code ne supprime pas les points que vous avez déjà sur votre chemin qui sont plus proches les uns des autres que le valeur d'espacement .
(La réponse originale "Intro to Markers" suit.)
Vous souhaitez définir un élément SVG <marker>
et ajouter les attributs marker-start="…"
Et/ou marker-end="…"
À votre ligne. L'utilisation d'un marqueur copie toute forme arbitraire aux extrémités de votre chemin et (avec orient="auto"
) Fait pivoter la forme pour qu'elle corresponde.
<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>
Au dessus:
orient="auto"
fait tourner le marqueur avec la lignemarkerWidth
et markerHeight
définissent une boîte englobante (comme une viewBox) à utiliser pour le marqueur. stroke-width
De la ligne finale; ayant une hauteur de "4", elle a une largeur de 20 unités dans le dessin final (4 × 5).refX
et refY
définissent où se trouve l '"origine" lors du placement de la forme à la fin du chemin refX="0.1"
Pour m'assurer que le marqueur chevauche légèrement la fin de la lignefill-opacity
Et stroke-opacity
Du marqueur et/ou de la ligne indépendamment, mais les modifications apportées au opacity
de la ligne affecteront également le marqueur dessiné. fill-opacity
Du marqueur, vous verriez le chevauchement; cependant, si vous abaissez le opacity
de la ligne elle-même, le marqueur est composé entièrement opaque sur la ligne et la combinaison des deux est alors réduite en opacité. Si vous voulez des flèches le long de la ligne, vous devrez utiliser marker-mid="…"
Avec <path>
Ou <polyline>
Et des points intermédiaires le long de la ligne.
Le seul problème est que tout point qui change de direction le long de la ligne gâche l'orientation ; c'est pourquoi dans la démo j'ai utilisé une courbe de Bézier pour arrondir le coin afin que le milieu de la ligne soit le long d'une section droite.
<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>
Pour ce faire, vous pouvez utiliser JavaScript et la commande getPointAtLength()
pour un chemin d'accès à exemple du chemin d'accès .
Je veux juste ajouter quelques liens et exemples utiles:
1. La flèche peut être quadratique
Documentation: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
<!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>