SVG <marker> 标记

SVG标签用于标签行或路径的开始、中间和结尾。例如,可以用圆或正方形标签路径的起点,用箭头标签路径的终点。marker元素定义了在特定的 <path>元素、 <line>元素、 <polyline>元素或者 <polygon>元素上绘制的箭头或者多边标签图形

Marker在线示例

这是一个简单的视觉示例,说明标记的外观:

标记是使用<marker>元素创建的。<marker> 元素必须嵌套在一个<defs>元素内。<defs>元素通常为SVG图像保留一组可重复使用的定义。
这是上面图形示例的SVG代码:

<svg width="500" height="100">
    <defs>
        <marker id="markerCircle" markerwidth="8" markerheight="8" refx="5" refy="5">
            <circle cx="5" cy="5" r="3" style="stroke: none; fill:#000000;"></circle>
        </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;"></path>
        </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);
                     "></path>
</svg>
测试看看 ‹/›

首先,请注意其中<defs>包含两个<marker> 元素的元素。这两个<marker>元素定义了上图中显示的开始和结束标记。
其次,注意<path>元素如何使用mark-start和marker-end CSS属性从其style属性内引用两个<mark>元素。 这就是为给定路径指定要使用的标记的方式。 稍后我会再谈到这个问题。

定义标记

您可以使用<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>

本示例定义了一个宽度为8(markerWidth=“8”)、高度为8(markerHeight=“8”)的标记。 由于标记是单独的图形元素,因此必须显式设置宽度和高度。

<mark>元素的id属性用于从<path>元素引用此标记。

refX和refY坐标设置标记内的点用作参考点。参考点是使用标记定位在路径开始处的点。在本示例中,refX和refY设置为圆的中心,这意味着圆的中心将放置在路径的起点处。如果不设置refX和refY,它们将被假定为0,这将使标记的左上角位于路径的开始处。

在<marker>元素内部是一个<circle>元素。 circle元素定义为以5,5为中心(cx和cy)。 中心点是标记虚拟框中的中心。 它不是实际放置在图像上的位置。 使用markerWidth和markerHeight在<marker>元素中将虚拟框的大小设置为8.8。

自动定向

这是另一个<marker>定义示例。本示例定义了用作路径箭头的三角形。

<svg width="500" height="100">
    <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;"></path>
        </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;" ></path>
        </marker>
    </defs>

    <path d="M100,20 l0,50"
          style="stroke: #0000cc; stroke-width: 1px; fill: none;
                       marker-start: url(#markerSquare);
                       marker-end: url(#markerArrow);
                       marker-mid: url(#markerSquare);
                     "
            ></path>

    <path d="M140,20 l25,50"
          style="stroke: #0000cc; stroke-width: 1px; fill: none;
                       marker-start: url(#markerSquare);
                       marker-end: url(#markerArrow);
                       marker-mid: url(#markerSquare);
                     "
            ></path>


    <path d="M180,20 l50,50"
          style="stroke: #0000cc; stroke-width: 1px; fill: none;
                       marker-start: url(#markerSquare);
                       marker-end: url(#markerArrow);
                       marker-mid: url(#markerSquare);
                     "
            ></path>

    <path d="M220,20 l50,25"
          style="stroke: #0000cc; stroke-width: 1px; fill: none;
                       marker-start: url(#markerSquare);
                       marker-end: url(#markerArrow);
                       marker-mid: url(#markerSquare);
                     "
            ></path>

    <path d="M260,20 l50,0"
          style="stroke: #0000cc; stroke-width: 1px; fill: none;
                       marker-start: url(#markerSquare);
                       marker-end: url(#markerArrow);
                       marker-mid: url(#markerSquare);
                     "
            ></path>

</svg>
测试看看 ‹/›

<marker>元素中的<path>将绘制一个尖端指向右侧的三角形。但是,如果路径不是水平线,则需要旋转三角形,使其适合使用它的路径的方向。可以通过将“方向”(orient)属性设定为“自动”(auto)来执行此操作。它将旋转<marker>元素内的形状以适合引用它的路径。

下面的图像显示了具有不同坡度的五条线,它们都使用相同的两个标记作为开始标记和结束标记。 请注意,标记如何自动旋转以适应使用它们的直线的坡度。

运行效果如下:

这是将<mark>元素中的orient属性设置为auto的结果。

也可以将orient属性的值设定为固定的度数(例如45度)。 这将使标记在使用时旋转该度数。 不过,这远不如自动定向功能有用。

从路径引用标记

您可以使用以下CSS属性从路径引用标记:

  • marker-start

  • marker-mid

  • marker-end

这三个CSS属性将标记分配给路径的起点,中点和终点。

CSS属性必须位于使用它们的<path>元素的style属性中。 您可以通过引用其id属性来引用<marker>元素,如下所示:

marker-start : url(#markerId);

markerId应该替换为要引用的<mark>元素的id属性的值。

这是使用所有三个CSS属性的示例:

<svg width="500" height="100">
    <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;"></path>
        </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;" ></path>
        </marker>
    </defs>

    <path d="M100,20 l0,50"
          style="stroke: #0000cc; stroke-width: 1px; fill: none;
                       marker-start: url(#markerSquare);
                       marker-end: url(#markerArrow);
                       marker-mid: url(#markerSquare);
                     "
            ></path>

    <path d="M140,20 l25,50"
          style="stroke: #0000cc; stroke-width: 1px; fill: none;
                       marker-start: url(#markerSquare);
                       marker-end: url(#markerArrow);
                       marker-mid: url(#markerSquare);
                     "
            ></path>


    <path d="M180,20 l50,50"
          style="stroke: #0000cc; stroke-width: 1px; fill: none;
                       marker-start: url(#markerSquare);
                       marker-end: url(#markerArrow);
                       marker-mid: url(#markerSquare);
                     "
            ></path>

    <path d="M220,20 l50,25"
          style="stroke: #0000cc; stroke-width: 1px; fill: none;
                       marker-start: url(#markerSquare);
                       marker-end: url(#markerArrow);
                       marker-mid: url(#markerSquare);
                     "
            ></path>

    <path d="M260,20 l50,0"
          style="stroke: #0000cc; stroke-width: 1px; fill: none;
                       marker-start: url(#markerSquare);
                       marker-end: url(#markerArrow);
                       marker-mid: url(#markerSquare);
                     "
            ></path>

</svg>
测试看看 ‹/›

运行结果如下:

从其他形状引用标记

<path>元素不是唯一可以使用标记的SVG元素。   <line>,<polyline>和<polygon>元素也可以使用标记。 它们以与<path>元素完全相同的方式进行操作:通过在标记开始,标记中间和标记结束(分别为:marker-start,marker-mid和marker-end)CSS属性中引用<marker>元素的id属性。

标记单位

可以将标记的大小设置为缩放,以适合使用它的路径的描边宽度。 下面是一个可视化示例:

通过将<marker>元素的markerUnits设置为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。 这样,无论使用它的路径的笔触宽度如何,标记都将保持其大小。