59

私は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>
4

2 に答える 2

175

質問の明確化に基づいて、属性が機能する<polyline>ように要素に沿って中間点を作成する実装を次に示します。marker-mid="url(#arrowhead)"マーカーと矢じりの概要については、以下を参照してください。

デモ: 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;
  }
}

上記のコードは、既存の要素を変更して、各直定規に沿って間隔<polyline>単位ごとにポイントを追加します。これをと組み合わせて、回転したマーカーをすべての頂点に配置すると、パスに沿って一貫して任意の複雑な形状/グラフィックを描画できます。marker-mid

バードトラック

上記のデモが示すように、コードは各セグメントに沿ってポイントを均等に配置しますが(コーナーで見苦しい「バンチング」が発生しないように)、コードは、間隔よりも接近しているパスにすでにあるポイントを削除しません。価値。


(元の「マーカーの概要」の回答は次のとおりです。)


SVG<marker>要素を定義し、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>​

デモ: http: //jsfiddle.net/Z5Qkf/1/

矢印の付いた曲線

上記の場合:

  • orient="auto"マーカーを線と一緒に回転させます
  • markerWidthmarkerHeightマーカーに使用するバウンディングボックス(viewBoxなど)を定義します
    • これらはstroke-width、最終行のによってスケーリングされることに注意してください。高さが「4」の場合、最終的な図面では幅が20単位になります(4×5)。
  • refXrefYパスの端にシェイプを配置するときに「原点」がどこにあるか を定義します
    • refX="0.1"マーカーが線の端とわずかに重なるようにするために使用しました
  • 自動方向を正しく機能させるには、マーカーの「順方向」を+x方向にする必要があります。(マーカーに使用される赤いパスは、回転していない場合、▶のようになります。)
  • マーカーや線のとを個別に調整できますが、線のを変更するとfill-opacity、描画されるマーカーにも影響します。 stroke-opacityopacity
    • 線とマーカーが重なっているため、マーカーを下げると重なっているfill-opacityことがわかります。ただし、opacity線自体を下げると、マーカーは線上で完全に不透明に合成され、2つの組み合わせの不透明度が下がります。
      ここに画像の説明を入力してください

線の長さに沿って矢印が必要な場合は、線に沿ったまたはおよび中間点のmarker-mid="…"いずれかで使用する必要があります。<path><polyline>

デモ: http: //jsfiddle.net/Z5Qkf/2/

ここに画像の説明を入力してください

唯一の問題は、線に沿って方向を変えるポイントが方向を台無しにすることです。これが、デモでベジェ曲線を使用して角を丸め、線の中点が直線に沿っている理由です。

<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()コマンドを使用して、パスをサンプリングします

于 2012-08-04T15:40:30.710 に答える
11

役立つリンクと例をいくつか追加したいだけです。

1.矢印は2次式にすることができます ここに画像の説明を入力してください

2.三次曲線 ここに画像の説明を入力してください

ドキュメント: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>

于 2018-09-20T21:07:08.193 に答える