吉本集の個人ブログ
Web制作の技術について書いています。たまに日記も書きます。

【SVG】マーカー要素(コンテナ要素)

2015年2月24日 / category : svg

marker要素は、line、path、polyline、polygonの要素に、矢印などのマーカを描画するグラフィックを定義します。
下記がmarker要素を使用した例です。
marker要素自体はグラフィック要素の指定によって使用されますので、defs要素内に記述しています。マーカーとして描画する要素はmarker要素内に記述します。例では、pathで定義しています。
実際には、line、path、polyline、polygonのグラフィック要素で使用しますが、その参照方法は、marker-start,marker-mid,marker-endプロパティのいずれかで指定します。
このプロパティに関しては、後述で紹介します。

HTML
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <defs>
  <marker id="arr" refX="0" refY="1">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
 </defs>
 <path d="M0,47 L230,47" stroke="#00ace5" stroke-width="10" marker-end="url(#arr)" />
 <path d="M0,140 L230,140" stroke="#00ace5" stroke-width="20" marker-end="url(#arr)" />
 <path d="M0,243 L230,243" stroke="#00ace5" stroke-width="30" marker-end="url(#arr)" />
</svg>

それでは、marker要素で使用する属性を紹介していきます。

refX : マーカーのX座標

HTML
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <defs>
  <marker id="x0" refX="2" refY="1">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
  <marker id="x1" refX="1" refY="1">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
  <marker id="x2" refX="0" refY="1">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
  <marker id="x3" refX="-1" refY="1">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
  <marker id="x4" refX="-2" refY="1">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
 </defs>
 <path d="M0,10 L260,10" stroke="#00ace5" stroke-width="10" marker-end="url(#x0)" />
 <path d="M0,80 L260,80" stroke="#00ace5" stroke-width="10" marker-end="url(#x1)" />
 <path d="M0,150 L260,150" stroke="#00ace5" stroke-width="10" marker-end="url(#x2)" />
 <path d="M0,220 L260,220" stroke="#00ace5" stroke-width="10" marker-end="url(#x3)" />
 <path d="M0,290 L260,290" stroke="#00ace5" stroke-width="10" marker-end="url(#x4)" />
</svg>

後述でmarkerUnits=”strokeWidth”の紹介をしますが、marker要素にmarkerUnits属性が無い場合は、markerUnits=”strokeWidth”が設定されます。
これは、marker要素の座標系の基準がstrokeの幅になるということを意味します。
そのため、例では、stroke-width=”10″となっておりますが、 marker要素のrefX属性が1の場合は、”10px”となります。
refX=”0″の場合は、”0px”なので、pathに対して空きのない状態でマーカーが配置されています。refX=”1″の場合は、”10px”の空きができ、反対にrefX=”-1″とすると、”-10px”の位置に配置されます。

refY : マーカのY座標

HTML
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <defs>
  <marker id="y0" refX="0" refY="2">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
  <marker id="y1" refX="0" refY="1">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
  <marker id="y2" refX="0" refY="0">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
  <marker id="y3" refX="0" refY="-1">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
  <marker id="y4" refX="0" refY="-2">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
 </defs>
 <path d="M0,10 L280,10" stroke="#00ace5" stroke-width="10" marker-end="url(#y0)" />
 <path d="M0,80 L280,80" stroke="#00ace5" stroke-width="10" marker-end="url(#y1)" />
 <path d="M0,150 L280,150" stroke="#00ace5" stroke-width="10" marker-end="url(#y2)" />
 <path d="M0,220 L280,220" stroke="#00ace5" stroke-width="10" marker-end="url(#y3)" />
 <path d="M0,290 L280,290" stroke="#00ace5" stroke-width="10" marker-end="url(#y4)" />
</svg>

refXはX座標でしたが、refYはY座標の設定です。
正数の場合は、上に移動するようです。

markerUnits=”strokeWidth” : ストローク幅を1単位とする座標系の値

HTML
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <defs>
  <marker id="s0" refX="0" refY="1" markerUnits="strokeWidth" markerWidth="0">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
  <marker id="s1" refX="0" refY="1" markerUnits="strokeWidth" markerWidth="1">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
  <marker id="s2" refX="0" refY="1" markerUnits="strokeWidth" markerWidth="2">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
 </defs>
 <path d="M0,45 L280,45" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#s0)" />
 <path d="M0,145 L280,145" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#s1)" />
 <path d="M0,245 L280,245" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#s2)" />
</svg>

refX属性のところで解説してしまいましたが、markerUnits=”strokeWidth”を設定すると、ストローク幅がmarker要素の座標系の基準となります。
stroke-width=”10″の場合、marker要素では1となります。
例では、markerWidthを指定しています。この値も、ストローク幅が基準になりますので、markerWidth=”1″の場合は、”10px”となります。
また、marker要素内のグラフィック要素であるpathにも適応されるため、

d=”M0,0 L2,1 0,2 Z”

これを”px”にすると、

d=”M0px,0px L20px,10px 0px,20px Z”

という感じになり、横幅20px、高さ20pxのグラフィック要素となります。
そこで、markerWidth=”1″を指定した場合は、横幅が半分の”10px”のみ表示されることになります。
markerWidth=”2″の場合は、横幅が”20px”なので、マーカーグラフィックスは全て表示されることになります。
逆に、markerWidth=”0″の場合は、横幅が”0px”なので、何も表示されない状態になります。

markerUnits=”userSpaceOnUse” : 利用要素の座標系の値

HTML
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <defs>
  <marker id="us0"
	 refX="10" refY="10" markerUnits="userSpaceOnUse" markerWidth="20" markerHeight="20">
   <rect x="0" y="0" width="20" height="20" fill="#eab942" />
  </marker>
  <marker id="us1"
	 refX="10" refY="10" markerUnits="userSpaceOnUse" markerWidth="20" markerHeight="20">
   <circle cx="10" cy="10" r="10" fill="#eab942" />
  </marker>
  <marker id="us2"
	 refX="10" refY="10" markerUnits="userSpaceOnUse" markerWidth="20" markerHeight="20">
   <polygon points="0,0 20,0 20,20 0,20" fill="#eab942" />
  </marker>
 </defs>
 <path d="M0,45 L280,45" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#us0)" />
 <path d="M0,145 L280,145" stroke="#00ace5" fill="none" stroke-width="20" marker-end="url(#us1)" />
 <path d="M0,245 L280,245" stroke="#00ace5" fill="none" stroke-width="30" marker-end="url(#us2)" />
</svg>

markerUnits=”strokeWidth”の場合は、使用するグラフィック要素のstroke-widthが基準になっていましたが、markerUnits=”userSpaceOnUse”の場合は、使用するマーカーのグラフィック要素それぞれそのまま指定した座標系が使用されるので、マーカーを使用するグラフィック要素のstroke-widthに依存することはありません。

marker-start / marker-mid / marker-end : マーカーを配置する基準

HTML
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <defs>
  <marker id="us0"
   refX="10" refY="10" markerUnits="userSpaceOnUse" markerWidth="20" markerHeight="20">
   <rect x="0" y="0" width="20" height="20" fill="#eab942" />
  </marker>
 </defs>
 <path d="M10,45 L280,45"
  stroke="#00ace5" fill="none" stroke-width="10" marker-start="url(#us0)" />
 <path d="M10,145 L140,190 280,145"
  stroke="#00ace5" fill="none" stroke-width="10" marker-mid="url(#us0)" />
 <path d="M10,245 L280,245"
  stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#us0)" />
</svg>

いままでの例では、marker-end属性でマーカーを指定していましたが、これはグラフィック要素の最後の頂点に描画する属性です。
marker-start属性は、最初の頂点に描画する属性、marker-mid属性は他のすべての頂点に描画する属性となります。

orient=”auto” : オート回転

HTML
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <defs>
  <marker id="arr2" refX="0" refY="1" orient="auto">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
 </defs>
 <path d="M150,150 L150,20" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#arr2)" />
 <path d="M150,150 L280,150" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#arr2)" />
 <path d="M150,150 L150,280" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#arr2)" />
 <path d="M150,150 L20,150" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#arr2)" />
</svg>

orient=”auto”を設定することで、マーカーの向きが自動的に、グラフィック要素の頂点の方向に合わせてくれます。

orient=角度 : 回転

HTML
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" version="1.1">
 <defs>
  <marker id="arr3" refX="0" refY="1" orient="45">
   <path d="M0,0 L2,1 0,2 Z" fill="#eab942" />
  </marker>
 </defs>
 <path d="M150,150 L150,20" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#arr3)" />
 <path d="M150,150 L280,150" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#arr3)" />
 <path d="M150,150 L150,280" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#arr3)" />
 <path d="M150,150 L20,150" stroke="#00ace5" fill="none" stroke-width="10" marker-end="url(#arr3)" />
</svg>

角度を入力すると、グラフィック要素の頂点の方向と関係なく、入力した角度の方向にマーカーが向きます。