16.SVG marker元素

SVG marker被用来标记线段或路径的开始、中间和结束。例如,你可以使用圆形或正方形标记作为路径的开始,并使用一个箭头标记路径的结束。

Marker示例

这里是一个简单的标记的视觉效果:

可以通过<marker>元素创建标记。<marker>元素必须嵌套在<defs>元素内。<defs>元素内通常保存一组可重用的SVG图片定义。

下面是之前那个例子的代码:

<defs>
    <marker id="markerCircle" markerWidth="8" markerHeight="8" refX="5" refY="5">
        <circle cx="5" cy="5" r="3" style="stroke: none; fill:#000000;"/>
    </marker>

    <marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6"
           orient="auto">
        <path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
    </marker>
</defs>

<path d="M100,10 L150,10 L150,60"
      style="stroke: #6666ff; stroke-width: 1px; fill: none;
                   marker-start: url(#markerCircle);
                   marker-end: url(#markerArrow);
                 "
        />

首先,请注意看内部带有两个<marker>元素的<defs>元素。两个<marker>元素定义了之前图片中展示的开始和结束标记。

然后,注意<path>元素如何通过其style属性,并使用CSS属性marker-startmarker-end引用这两个<marker>元素。这就是如何为一个给定路径指定标记的方法。我们稍后再看。

定义Marker

你可以使用<marker>元素定义标记。示例代码如下:

<marker id="markerCircle" markerWidth="8" markerHeight="8" refX="5" refY="5">
    <circle cx="5" cy="5" r="3" style="stroke: none; fill:#000000;"/>
</marker>

这个例子定义了一个宽度(markerWidth="8")和高度(markerHeight="8")都为8的标记。宽度和高度需要显示设置,因为标记是一个独立的图形元素。

<marker>元素的id属性是用来在<path>元素中对其引用。

标记中的refXrefY坐标集被用作参考点。参考点是使用此标记的路径的开始位置。此例子中,refXrefY设置为圆的中心,意味着圆的中心将被放在路径的开始位置。如果未设置refXrefY,其默认为0,即标记的左上角会被放在路径的开始处。

<marker>元素中是一个<circle>元素。circle元素的圆心(cxcy)在点5,5。中心点是标记虚拟框内的中心。它不在实际放置在图像中的位置。在<marker>元素上使用markerWidthmarkerHeight将虚拟框的大小设置为8,8。

自动定向

下面是另一个定义<marker>的例子。此例子定义了用作路径箭头的三角形。

<marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6"
       orient="auto">
    <path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
</marker>

<path>内部的<marker>元素绘制了一个箭头指向右边的三角形。然而,如果路径不是一条水平线,你就需要旋转三角形来适应路径的方向。你可以将orient属性设置为auto来实现上述效果。<marker>元素将会旋转其内部的图形,来适应引用它的路径。

下图展示了具有不同斜率的五条线,它们都使用了两个相同的标记作为起始和结束。注意标记是如何自动旋转以适应它们的线的斜率。

这就是将<marker>元素中的orient属性设置为auto达到的效果。

你也可以将orient属性值设置为固定的角度(如45)。这将导致标记旋转指定的角度。然而,这并不如自动定向功能那么有用。

在Path中应用Marker

你可以在path上使用这些CSS属性引用标记:

  • marker-start

  • marker-mid

  • marker-end

这三个CSS属性分别为路径的开始、中间点和结束指定标记。

必须在<path>元素的style属性中使用这些CSS属性。你可以通过标记的id属性来引用它,就像下面这样:

marker-start: url(#markerId);

markerId<marker>元素的id属性值替换。

下面示例中使用了上述三个CSS属性:

<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"
      style="stroke: #0000cc; stroke-width: 1px; fill: none;
                   marker-start: url(#markerSquare);
                   marker-mid: url(#markerSquare);
                   marker-end: url(#markerArrow);

                 "
        />

结果图片如下:

在其它形状中引用Marker

<path>元素不是SVG元素中唯一可以使用标记的元素。<line><polyline><polygon>元素也可以使用标记。它们和<path>引用标记的方式完全一样:在CSS属性marker-startmarker-midmarker-end中引用<marker>元素的id属性。

标记单位

标记的大小可以设置为适应路径边框宽度。这里有一个可视化的例子:

你可以将<marker>元素的makerUnits设置为strokeWidth达到此效果。这实际上也是它的默认值,因此即使你未设置markerUnits属性,默认会达到此效果。SVG代码如下:

<marker id="markerSquare" markerWidth="7" markerHeight="7" refX="4" refY="4"
    orient="auto" markerUnits="strokeWidth">
    <rect x="1" y="1" width="5" height="5" style="stroke: none; fill:#000000;"/>
</marker>

避免标记自动缩放以适应路径的边框宽度,请将markerUnits属性设置为userSpaceOnUse。这样,标记将保持其大小,而不管使用它的路径的边框宽度如何变化。

最后更新于