marker原意为标记,在svg里,通过marker标签可以定义一个或多个标记,然后目标对象(使用者)通过 marker-start、marker-mid 和 marker-end 加入定义好的标记。请看如下效果,我们使用了marker标签设置了小圆点标记,令其贴付到线段的两端:
这是如何做到的?一切归功于 marker 标签。和 pattern 标签一样,marker 标签也要嵌套在 defs 标签之内,defs标签在svg里经常用于封装可以复用的东西。以下是上例的 marker 标记代码结构:
<defs>
<marker id="mdot" markerWidth="8" markerHeight="8" refX="4" refY="4">
<circle cx="4" cy="4" r="4" fill="purple" />
</marker>
</defs>
从代码中,我们应该能发现,marker标签有自己的id属性,它是使用者调用marker的唯一标识;markerWidth 和 markerHeight 这两个属性,顾名思义,是标记图像的宽高尺寸,注意两个属性组合名称的写法;refX 属性定义了marker标记图像参考点的X坐标,refY 属性定义的是marker标记图像的Y坐标,这两个属性如果不设置,标记图像可能会脱离调用者的主体。此外,marker标签还有一个重要的属性,orient,原意为定向,用于规定标记图像的转向,上例的标记是圆形无需指定朝向,所以没有设置它。而用做标记图形的元素,如你所看到的,上例使用的是一个 circle 标签,其XY坐标和半径都是 4,填充颜色为紫色。这里需要注意,用做标记的实体图形(例如例中的circle),它们的定位、尺寸应基于marker标签。
然后,我们用 line 标签画一根长200的线段,使用 marker-start 和 marker-end 声明线段的头尾调用 id="mdot" 的marker标记:
<line x1="20" y1="20" x2="220" y2="20" stroke="navy" stroke-width="2" marker-start="url(#mdot)" marker-end="url(#mdot)" />
如你所见,marker-start 和 marker-end 这两个属性,通过 url(#id) 的方式调用设计好的marker标记。
附上上例的完整代码,以供童鞋们学习研究(svg的边框已在CSS中定义):
<svg width="240" height="40">
<defs>
<marker id="mdot" markerWidth="8" markerHeight="8" refX="4" refY="4">
<circle cx="4" cy="4" r="4" fill="purple" />
</marker>
</defs>
<line x1="20" y1="20" x2="220" y2="20" stroke="navy" stroke-width="2" marker-start="url(#mdot)" marker-end="url(#mdot)" />
</svg>
如果想在线段的中间也加入一个圆点标记,可以吗?答案是,上例不可以。marker-mid 这个属性,并不是在一根线段的中央贴付标记,而是,在一个有开头有结尾的组合线段中,中间的线段斜街通过 marker-mid 属性定义标记。以下的两个图案都贴付了圆点marker标记,第一个是 path 标签做成的三节线段,中间的两个圆点就是线段的衔接处;第二个用 polyline 标签画成闭合的图案,因为头尾衔接所以不设置 marker-end 属性,右边的三个圆点都是 marker-mid 属性定义的:
再附上上例svg代码(它们调用的marker标记是前例定义的 mdot):
<svg width="340" height="200">
<path d="M20 20 l100 0 l100 0 l100 0" fill="none" stroke="navy" stroke-width="2" marker-start="url(#mdot)" marker-mid="url(#mdot)" marker-end="url(#mdot)" />
<polyline points="10 100,150 125,150 175,200 100, 10 100" fill="rgba(50,200,50,.5)" stroke="green" stroke-width="2" marker-start="url(#mdot)" marker-mid="url(#mdot)" />
</svg>
【提示】虽然我们定义了marker的宽高尺寸,但标记的大小不是绝对的,它依赖于调用者的 stroke-width 属性值的设置。有兴趣的童鞋可以尝试更改 stroke-width 值,看看发生什么。