SVGマーカー:位置のずれない独自の矢印先端を作る
独自のSVG矢印先端を作り、先端の位置と開始側の向きを調整します。ブラウザーで描画した独自の例で、2つのストローク幅でのサイズを比較します。
目次
SVGパスへ独自の矢印先端を付けるには、画像を<marker>内に定義し、marker-endでIDを参照します。画像のどの点をパスの端点に合わせるか、refXとrefYで指定します。その後、パスに合わせて回転させるか、ストローク幅に合わせて大きくするかを選びます。
これらは別々の問題を解決します。矢印の方向が正しくても、端点からずれる場合があります。細い線では正しく合っていても、線を太くすると大きすぎる場合もあります。この手順では、独自のポインター形状を使い、配置、方向、サイズを分けて扱います。
小さな完全なSVGから始める
以下をmarkers.svgとして保存し、ブラウザーで開きます。ポインターは手書きの例で、12 × 12の座標空間内の(11, 6)に先端があります。PerfectVectorの変換結果ではありません。
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 180">
<defs>
<marker id="pv-pointer" viewBox="0 0 12 12"
refX="11" refY="6" markerWidth="6" markerHeight="6"
markerUnits="strokeWidth" orient="auto-start-reverse">
<path d="M1 1 L11 6 L1 11 L4 6 Z" fill="#087f82"/>
</marker>
</defs>
<g fill="none" stroke="#20364d" stroke-width="4"
marker-start="url(#pv-pointer)" marker-end="url(#pv-pointer)">
<path d="M50 45 H350"/>
<path d="M50 135 C130 75,260 195,350 135"/>
</g>
</svg>最初のパスは直線、2つ目は曲線です。両方の両端で同じマーカーを参照します。<defs>は定義を保存し、パスからの参照が表示します。MDNのmarkerリファレンスは、開始、中間、終点の取り付け属性を説明しています。
包含する文書内で一意のIDを使います。複数のSVGをインラインで組み合わせる場合は、マーカーIDに接頭辞を付け、対応するすべてのurl(#...)参照を更新します。SVGのsymbolスプライトガイドは、再利用アイコンでの同じ参照管理の問題を説明しています。
意図した点を端点に合わせる
refX="11" refY="6"は、マーカー画像のどの点をパスの端点に一致させるかを指定します。パス自体は動かしません。この例では、尖った先端です。
refX="0" refY="0"と比較します。ブラウザーはマーカーの座標原点を端点へ配置し、水平線では先端がさらに右下へずれます。マーカーを大きくすると誤りが目立つだけで、基準点は直りません。
MDNはrefXとrefYを、マーカーの参照点の座標として説明しています。表示幅から推測せず、viewBoxを含む画像自身の座標で読み取ります。

完全なSVGを別途開き、ブラウザーで比較を描画しました。参照点を変えると先端がオレンジの十字に合いました。方向を変えると開始側の矢印が反転しました。単位モードを変えると、ポインターが線とともに大きくなるかを制御できました。これらはこの例の観察結果です。実際の書き出しファイルを受け取り側のアプリで確認します。
先端を端点に正確に合わせても、ストロークはその点まで伸びています。比較にあるように、太い線では細い先端の横にストロークが見える場合があります。その継ぎ目が重要なら、モチーフ、基準点、パス端点を一緒に調整し、接合を確認します。マーカーの配置は、元のストロークを切り取りません。
曲線に方向を決めさせる
パスの終端の矢印には、orient="auto"がその点でのパス方向に従います。曲線の終わりの方向は局所的な接線から決まるため、矢印はパスの両端を結ぶ直線の方向を向くとは限りません。
両端の矢印にはorient="auto-start-reverse"を使います。終端ではautoと同じで、開始マーカーはさらに180度回転します。MDNのorientドキュメントは、両端から外向きの1つの矢印先端を再利用する方法として説明しています。
右上の比較で違いが分かります。autoでは開始ポインターが曲線に沿って向きます。auto-start-reverseでは開始点の外側へ向きます。手で反転した2つ目の形を用意する必要はありません。
予想外の結果なら、パス方向を確認します。パスを反転すると、どちらの端が開始点かが変わります。流れを示す矢印は、両端の画面位置が以前と同じでも、その方向に応じて付ける必要があります。
線の太さでマーカーのサイズを変えるか決める
markerUnitsは、マーカーの寸法と内容の座標系を設定します。既定値はstrokeWidthで、もう一方はuserSpaceOnUseです。違いはMDNのmarkerUnitsリファレンスを参照してください。
| 選択 | ストロークを4から8にした場合 | 役立つ場面 |
|---|---|---|
strokeWidth | マーカー寸法が2倍になります | 矢印先端を線の太さに比例させる場合 |
userSpaceOnUse | 参照要素のユーザー座標では寸法が同じです | 線の太さが異なってもモチーフのサイズを保つ場合 |
ポインターはviewBoxの水平12単位のうち10単位を占めます。markerWidth="6"とmarkerUnits="strokeWidth"では、回転前の幅は10 / 12 × 6 × stroke-widthです。4単位のストロークでは20ユーザー単位、8単位では40です。左下の比較はその設定を使います。
両方の線の太さでポインター幅を20単位に保つには、定義を次に変えます。
markerUnits="userSpaceOnUse" markerWidth="24" markerHeight="24"右下の比較はこれらの値です。markerWidth="6"を維持して単位モードだけ変えると、6単位がストローク幅で乗算されなくなるため、ポインターはずっと小さくなります。
userSpaceOnUseは、画面ピクセル数の固定を意味しません。周囲のSVGや座標系を拡大縮小すると、表示サイズは変わる場合があります。特に大きなモチーフを小さな図の注記に縮小する場合は、最終レイアウトのサイズで確認します。
マーカーにする前に独自のモチーフを準備する
三角形や単純なポインターは、直接パスを描きます。既存のベクター画像では元パスを保持し、どの座標を線へ付けるか決めます。意図した穴を保持し、最終サイズで消える細部を簡略化して、マーカービューポート内に十分な余裕を与えます。
独自の矢印先端や装飾モチーフがPNGやJPGでしか残っていない場合は、PerfectVectorの画像をベクターに変換する手順で、この組み込みの前にSVG候補を復元できます。輪郭と小さな穴を元画像と比較し、不要な背景形状を削除してから、承認した画像の境界と基準点を選びます。変換はマーカー定義を作ったり、パス方向を割り当てたり、図のコネクターの動作を加えたりはしません。
テスト中は色を明示します。この例は青緑のマーカーと紺の線を使い、境界が見えるようにしています。矢印全体を1色にしたい場合は、両方の描画設定を意図して設定し、納品結果を確認します。SVGの色編集ガイドは、色変更を妨げる固定の塗りとスタイルを扱っています。
実際に使う場所でファイルを確認する
編集可能なマスターを保持し、納品用コピーを実際のWebサイト、エディター、書き出し工程で試します。正しいブラウザープレビューは、そのファイルのブラウザーでの見た目を確認するもので、すべてのアプリの読み込み動作を保証しません。
- 組み込みや最適化後に、各
url(#...)が意図したマーカーIDを参照するか確認します。 - 開始マーカーも使う場合は含めて、直線と曲線を確認します。
- デザイン内の最も細い線と太い線を比較します。
- 最終表示サイズで、先端、接合部、切れた画像を確認します。
- 納品SVGを独立して開き直し、元のプレビューと比較します。
マーカーは、パス上の位置に付ける見える装飾です。図のオブジェクト間に意味的な接続を作るものではありません。図のエディターの接続点やステンシルの動作には、ネイティブの形状システムを使います。draw.ioのカスタム形状ガイドは、その別の作業を扱っています。
マーカーは、物理的につながったカット輪郭にも自動ではなりません。対象環境に閉じたカット形状が必要なら、ベクターエディターで別のパスベースの納品用コピーを準備して確認します。画面上で線と矢印先端が重なっても、結合した輪郭の証拠ではありません。他のSVG準備ガイドは、画像整理と後工程の確認を扱っています。
よくある質問
SVGの矢印先端が線からずれるのはなぜですか? マーカー画像の座標に対してrefXとrefYを確認します。それらはパス端点へ置く点を特定します。この例の先端は11,6で、0,0を使うと原点が端点に置かれます。
1つの矢印先端を両端に再利用するにはどうすればよいですか? marker-startとmarker-endで同じマーカーを参照し、orient="auto-start-reverse"を使います。開始側は反転し、終端側はパス方向に従います。
線を太くすると矢印先端が大きくなるのはなぜですか? markerUnitsの既定値がstrokeWidthだからです。要素のユーザー座標でサイズを保ちたいならuserSpaceOnUseを使い、その単位系に合わせてmarkerWidthとmarkerHeightを調整します。
マーカーは矢印を1つの閉じたパスにしますか? いいえ。マーカー定義は、参照するパスとは別のままです。後工程のカットや編集に必要なら、実際に結合した形状を準備して確認します。
参考資料
- MDN — marker — マーカー定義、対応形状、取り付け属性。
- MDN — refX — マーカー座標系での水平参照点の配置。
- MDN — refY — マーカー座標系での垂直参照点の配置。
- MDN — orient — 自動回転と開始インスタンスの反転。
- MDN — markerUnits — ストロークに対するサイズとユーザー座標でのサイズ。
1つのモチーフから始め、直線と曲線の両方で基準点、方向、サイズを確認します。モチーフがラスターしかない場合は、SVG候補を準備し、輪郭と開口部を確認してから、承認したパスをマーカーとして組み込みます。
