SVG <markers>用法

admin發表於2018-09-13

實際應用中,可能需要線上段的開始或者結尾新增一個箭頭或者其他型別標記。

SVG提供了<markers>元素可以很好的實現上述功能,可以標記一條線或路徑開始、中間或結束位置。

marker翻譯成漢語具有標識或者標記意思,或多或少對此標籤的理解記憶有所幫助。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
</head>
<body>
<svg width="500" height="500">
  <defs>
    <marker id="arrow"
            markerWidth="10" markerHeight="10"
            refX="0" refY="3"
            orient="auto"
            markerUnits="strokeWidth"
            viewBox="0 0 20 20">
      <path
            d="M0,0 L0,6 L9,3 z"
            fill="#f00"
            />
    </marker>
  </defs>
  <line
        x1="50" y1="50"
        x2="250" y2="50"
        stroke="#000"
        stroke-width="3"
        marker-end="url(#arrow)" />
</svg>  
</body>
</html>

程式碼演示了<markers>元素的使用,它在一條直線的末端新增一個紅色三角形箭頭。

下面分步介紹一下<markers>元素的相關屬性:

(1).id屬性:

其他元素會利用<markers>元素的id屬性進行引用。

比如上面的程式碼片段:

[XML] 純文字檢視 複製程式碼
marker-end="url(#arrow)"

<line>元素的marker-end屬性值為"url(#arrow)","arrow"是<markers>元素的id屬性值。

(2).markerWidth和markerHeight屬性:

<markers>元素建立一個viewport視窗,上述兩個屬性用來規定視窗的尺寸。

(3).refX和refY屬性:

規定<markers>元素內建立的圖形元素哪個位置與指定圖形元素相連線。

refX="0" refY="3"規定三角形的(0,3)位置與直線的末端相連線。

所屬座標系是<markers>元素建立視窗內的當前使用者座標系。

(4).orient屬性:

前面程式碼是一條水平直線與箭頭相連線。

如果這條直線是傾斜的,那是不是也要人為的調整箭頭的方向呢。

不需要,只需要將orient屬性值設定為"auto"即可。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
</head>
<body>
<svg width="500" height="500">
  <defs>
    <marker id="arrow"
            markerWidth="10" markerHeight="10"
            refX="0" refY="3"
            orient="auto"
            markerUnits="strokeWidth"
            viewBox="0 0 20 20">
      <path
            d="M0,0 L0,6 L9,3 z"
            fill="#f00"
            />
    </marker>
  </defs>
  <line
        x1="50" y1="50"
        x2="250" y2="150"
        stroke="#000"
        stroke-width="3"
        marker-end="url(#arrow)" />
</svg>  
</body>
</html>

儘管直線傾斜了一定角度,但是三角形箭頭還是完美的與直線連線起來,如果去掉orient。

執行效果截圖如下:

1.jpg

當然也可以人為的規定一角度值,比如50deg(可以不帶單位)。

程式碼片段如下:

[XML] 純文字檢視 複製程式碼
orient="90"

(5).markerUnits屬性:

從屬性名稱可以猜測功能,用來規定<marker>以及其中繪製的圖形的尺寸是以什麼為單位的。

屬性值可以是"strokeWidth"(預設)或者"userSpaceOnUse"。

以上面程式碼為例:

(1)."strokeWidth",那麼markerWidth="10"實際尺寸就是10乘以line元素的stroke-width值,其他資料同理。

(2)."userSpaceOnUse",那麼各個資料的值你規定多少就是多少(是一個絕對值)。

(6).viewBox屬性:

<markers>元素會建立一個viewport視窗,所以它也有viewBox。

關於viewBox具體用法參閱SVG viewBox和preserveAspectRatio用法詳解一章節。

圖形元素引用<markers>:

圖形元素可以使用以下三個屬性來引用<markers>元素:

(1).marker-start:表示連線路徑的開始位置。

(2).marker-mid:表示連線路徑的中間位置(後面會具體說明)。

(3).marker-end:表示連線路徑的結束位置。

屬性值都是如下格式:

[XML] 純文字檢視 複製程式碼
marker-start : url(#markerId);

#markerId是<markers>元素的id屬性值。

程式碼例項:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
</head>
<body>
<svg width="500" height="500">
  <defs>
    <marker id="markerSquare"
            markerWidth="7"
            markerHeight="7"
            refX="4" refY="4"
            orient="auto">
      <rect x="1" y="1"
            width="5"
            height="5"
            style="stroke:none; fill:#000000;" />
    </marker>
    <marker id="markerArrow"
            markerWidth="13"
            markerHeight="13"
            refX="2" refY="7"
            orient="auto">
      <path d="M2,2 L2,13 L8,7 L2,2" style="fill:#000000;"/>
    </marker>
  </defs>
 
  <path d="M100,20 l50,0 l0,50 l50,0"
        marker-start="url(#markerSquare)"
        marker-mid="url(#markerSquare)"
        marker-end="url(#markerArrow)"
        style="stroke:#0000cc;stroke-width:1px;fill: none;"
        />
</svg>  
</body>
</html>

marker-start和marker-end比較直白,就是連線路徑的開始和結尾處。

marker-mid可能會產生一些誤解,放置<markers>的"中間"位置存在於路徑的連線之處。

程式碼片段如下:

[XML] 純文字檢視 複製程式碼
"M100,20 l50,0 l0,50 l50,0"

"M100,20 l50,0"直線是"一筆"下來,中間沒有連線點,"M100,20 l50,0 l0,50"則有一個連線點"l50,0"。

於是就會在連線點處放置一個<markers>,以此類推。

特別說明:如果<markers>有兩個連線點,如上面程式碼中間的<markers>,那麼marker的x軸正向與兩個path的夾角的角等分線走向一致。