私はSVGを初めて使用し、2つのポイント間に直線を描画しようとしています。これまでのところ、次のコマンドを使用して管理しました。
<line x1="50" y1="50" x2="150" y2="150" style="stroke:rgb(255,255,0); stroke-width:2" stroke-dasharray="5,3" />"
方向を示すために、この線の上に小さな三角形または矢印の頭(等間隔)を追加する最も簡単な方法は何ですか?
編集1:
より明確にするために、私は線の終わりにある矢印の後ろではなく、線全体に沿って複数の三角形(等間隔)を探しています。可能であれば、破線の各ダッシュを、線の方向を指す三角形に置き換えます。
編集2
Phrogzの提案に基づいて、次のようなページを作成しましたが、何も表示されません。私は何を間違えていますか?
<%@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>
質問の明確化に基づいて、marker-mid="url(#arrowhead)"
属性が機能するように_<polyline>
_要素に沿って中間点を作成する実装を次に示します。マーカーと矢印の概要については、以下を参照してください。
_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>
_要素を変更して、各直線エッジに沿ってspacing単位ごとにポイントを追加します。これを_marker-mid
_と組み合わせて、すべての頂点に回転マーカーを配置すると、パスに沿って任意の複雑な形状/グラフィックを一貫して描画することができます。
上記のデモが示すように、コードは各セグメントに沿ってポイントを均等に配置しますが(コーナーで見苦しい「バンチング」が発生しないように)、コードはspacing値。
(元の「マーカーの紹介」の回答が続きます。)
SVG _<marker>
_ element を定義し、_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>
_
上記で:
orient="auto"
_ は、マーカーを線と一緒に回転させますmarkerWidth
およびmarkerHeight
マーカーに使用する境界ボックス(viewBoxなど)を定義します。stroke-width
_でスケーリングされることに注意してください。高さを「4」にすると、最終的な図面で幅が20単位(4×5)になります。refX
and refY
パスの端に形状を配置するときの「Origin」の位置を定義しますrefX="0.1"
_を使用して、マーカーが行の終わりにわずかに重なるようにしましたfill-opacity
_および_stroke-opacity
_を個別に調整できますが、行のopacity
への変更は、描画されたマーカーにも影響します。fill-opacity
_を下げるとオーバーラップが表示されます。ただし、ライン自体のopacity
を下げると、マーカーはライン上で完全に不透明に合成され、2つの組み合わせは不透明度が下がります。線の長さに沿って矢印が必要な場合は、_marker-mid="…"
_を_<path>
_または_<polyline>
_とともに使用し、線に沿った中間点を使用する必要があります。
唯一の問題は、線に沿って方向を変える点 方向を台無しにする ;そのため、デモでは、ベジエ曲線を使用して角を丸めて、線の中点が直線部分に沿っているようにしました。
_<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()
コマンドを使用して、 パスのサンプル へのパスを指定します。
役に立つリンクと例を追加したいだけです。
ドキュメント: 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>