马黑黑 发表于 2023-11-6 09:29

svg 标记标签 : marker(一)

本帖最后由 马黑黑 于 2023-11-6 09:38 编辑 <br /><br /><style>
.ma p, .ma pre, .ma svg { margin: 8px 0; }
.rred { color: red; }
.zs { color: green; }
.ma pre { padding: 16px; background: #efefef; font: normal 16px monospace; white-space: pre-wrap; word-wrap: break-word; tab-size: 4; line-height:1.5em; }
.ma svg { border: 1px solid gray; }
</style>

<h2>marker标签(一)</h2>
<div class="ma">

<p>marker原意为标记,在svg里,通过marker标签可以定义一个或多个标记,然后目标对象(使用者)通过 marker-start、marker-mid 和 marker-end 加入定义好的标记。请看如下效果,我们使用了marker标签设置了小圆点标记,令其贴付到线段的两端:</p>

<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>

<p>这是如何做到的?一切归功于 marker 标签。和 pattern 标签一样,marker 标签也要嵌套在 defs 标签之内,defs标签在svg里经常用于封装可以复用的东西。以下是上例的 marker 标记代码结构:</p>

<pre>
        &lt;defs>
                &lt;marker id="mdot" <span class="rred">markerWidth="8" markerHeight="8" refX="4" refY="4"</span>&gt;
                        &lt;circle cx="4" cy="4" r="4" fill="purple" /&gt;
                &lt;/marker&gt;
        &lt;/defs&gt;
</pre>

<p>从代码中,我们应该能发现,marker标签有自己的id属性,它是使用者调用marker的唯一标识;<span class="rred">markerWidth</span> 和 <span class="rred">markerHeight</span> 这两个属性,顾名思义,是标记图像的宽高尺寸,注意两个属性组合名称的写法;<span class="rred">refX</span> 属性定义了marker标记图像参考点的X坐标,<span class="rred">refY</span> 属性定义的是marker标记图像的Y坐标,这两个属性如果不设置,标记图像可能会脱离调用者的主体。此外,marker标签还有一个重要的属性,<span class="rred">orient</span>,原意为定向,用于规定标记图像的转向,上例的标记是圆形无需指定朝向,所以没有设置它。而用做标记图形的元素,如你所看到的,上例使用的是一个 <span class="rred">circle</span> 标签,其XY坐标和半径都是 4,填充颜色为紫色。这里需要注意,用做标记的实体图形(例如例中的circle),它们的定位、尺寸应基于marker标签。</p>

<p>然后,我们用 line 标签画一根长200的线段,使用 marker-start 和 marker-end 声明线段的头尾调用 id="mdot" 的marker标记:</p>

<pre>
&lt;line x1="20" y1="20" x2="220" y2="20" stroke="navy" stroke-width="2" <span class="rred">marker-start="url(#mdot)" marker-end="url(#mdot)"</span> /&gt;
</pre>

<p>如你所见,marker-start 和 marker-end 这两个属性,通过 <span class="rred">url(#id)</span> 的方式调用设计好的marker标记。</p>

<p>附上上例的完整代码,以供童鞋们学习研究(svg的边框已在CSS中定义):</p>

<pre>
&lt;svg width="240" height="40"&gt;
        &lt;defs&gt;
                &lt;marker id="mdot" markerWidth="8" markerHeight="8" refX="4" refY="4"&gt;
                        &lt;circle cx="4" cy="4" r="4" fill="purple" /&gt;
                &lt;/marker&gt;
        &lt;/defs&gt;

        &lt;line x1="20" y1="20" x2="220" y2="20" stroke="navy" stroke-width="2" marker-start="url(#mdot)" marker-end="url(#mdot)" /&gt;
&lt;/svg&gt;
</pre>

<p>如果想在线段的中间也加入一个圆点标记,可以吗?答案是,上例不可以。marker-mid 这个属性,并不是在一根线段的中央贴付标记,而是,在一个有开头有结尾的组合线段中,中间的线段斜街通过 marker-mid 属性定义标记。以下的两个图案都贴付了圆点marker标记,第一个是 path 标签做成的三节线段,中间的两个圆点就是线段的衔接处;第二个用 polyline 标签画成闭合的图案,因为头尾衔接所以不设置 marker-end 属性,右边的三个圆点都是 marker-mid 属性定义的:</p>

<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>

<p>再附上上例svg代码(它们调用的marker标记是前例定义的 mdot):</p>

<pre>
&lt;svg width="340" height="200"&gt;
        &lt;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)" /&gt;
        &lt;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)" /&gt;
&lt;/svg&gt;
</pre>

<p>【提示】虽然我们定义了marker的宽高尺寸,但标记的大小不是绝对的,它依赖于调用者的 stroke-width 属性值的设置。有兴趣的童鞋可以尝试更改 stroke-width 值,看看发生什么。</p>

</svg>
</div>

红影 发表于 2023-11-6 14:50

“它依赖于调用者的 stroke-width 属性值的设置。”
看到了,调整 stroke-width 变大,标记自动跟着变化{:4_187:}

红影 发表于 2023-11-6 15:07

设置refX="4" refY="4"都是0的时候,标志向右下方向跑了。都取8对应到线段点的左上了。
也就是必须在标注的中心点上,才能正确对应线段的起点或终点。

红影 发表于 2023-11-6 15:10

标志跟随线段的 stroke-width 同步变化,这个挺神奇的。
好处是重复调用时能适应不同线宽。虽然标志的大小可以设置,但设置后就认真地跟随宽度变了。

马黑黑 发表于 2023-11-6 23:13

红影 发表于 2023-11-6 14:50
“它依赖于调用者的 stroke-width 属性值的设置。”
看到了,调整 stroke-width 变大,标记自动跟着变化{: ...

实际上,marker也有自己的 viewBox 属性,该属性在marker标签里,和svg一样,有缺省值;但pattern如果不设置viewBox,则不启用该属性,亦即pattern的viewBox没有缺省值。

马黑黑 发表于 2023-11-6 23:15

红影 发表于 2023-11-6 15:07
设置refX="4" refY="4"都是0的时候,标志向右下方向跑了。都取8对应到线段点的左上了。
也就是必须在标注 ...

对。refX和refY这两个值,其实是标记与调用者主体的对齐方式。

马黑黑 发表于 2023-11-6 23:16

红影 发表于 2023-11-6 15:10
标志跟随线段的 stroke-width 同步变化,这个挺神奇的。
好处是重复调用时能适应不同线宽。虽然标志的大小 ...

可以根据需要设置不同的marker标记备用

红影 发表于 2023-11-7 15:38

马黑黑 发表于 2023-11-6 23:13
实际上,marker也有自己的 viewBox 属性,该属性在marker标签里,和svg一样,有缺省值;但pattern如果不 ...

哦,也就是说marker自带 viewBox 属性呗。

红影 发表于 2023-11-7 15:39

马黑黑 发表于 2023-11-6 23:15
对。refX和refY这两个值,其实是标记与调用者主体的对齐方式。

这个标志的设置数据还挺多的。

红影 发表于 2023-11-7 15:40

马黑黑 发表于 2023-11-6 23:16
可以根据需要设置不同的marker标记备用

哦,这也是个法子,多设置几个,想用哪个就用哪个{:4_173:}

马黑黑 发表于 2023-11-7 19:15

红影 发表于 2023-11-7 15:40
哦,这也是个法子,多设置几个,想用哪个就用哪个

一般都是设计很多个的

马黑黑 发表于 2023-11-7 19:16

红影 发表于 2023-11-7 15:39
这个标志的设置数据还挺多的。

svg的标签都大概如此

马黑黑 发表于 2023-11-7 19:16

红影 发表于 2023-11-7 15:38
哦,也就是说marker自带 viewBox 属性呗。

对,和svg是一样的

红影 发表于 2023-11-7 20:46

马黑黑 发表于 2023-11-7 19:15
一般都是设计很多个的

反正有对应的id,也不会用错。

红影 发表于 2023-11-7 20:48

马黑黑 发表于 2023-11-7 19:16
svg的标签都大概如此

<marker id="mdot" markerWidth="8" markerHeight="8" refX="4" refY="4">

这里的宽高好像没什么用吧,跟着下面图形的宽高不行么?

红影 发表于 2023-11-7 20:49

马黑黑 发表于 2023-11-7 19:16
对,和svg是一样的

改变线宽,标注跟着变化,就是因为 viewBox 起作用吧?

马黑黑 发表于 2023-11-8 07:39

红影 发表于 2023-11-7 20:48
这里的宽高好像没什么用吧,跟着下面图形的宽高不行么?

可以一样,也可以不一样,因为marker有viewBox

红影 发表于 2023-11-8 20:01

马黑黑 发表于 2023-11-8 07:39
可以一样,也可以不一样,因为marker有viewBox

哦哦,是的,忘了这个了。这样,那还是必须要设置的。

马黑黑 发表于 2023-11-9 12:21

红影 发表于 2023-11-8 20:01
哦哦,是的,忘了这个了。这样,那还是必须要设置的。

一般的做法是大家一样

红影 发表于 2023-11-9 15:08

马黑黑 发表于 2023-11-9 12:21
一般的做法是大家一样

嗯嗯,做成一样的,就不会出问题。
页: [1] 2
查看完整版本: svg 标记标签 : marker(一)