马黑黑 发表于 2024-10-28 20:49

svg : marker 标记

<style>
svg { outline: 1px solid gray; }
.wrap { font: normal 18px/24px sans-serif; }
.wrap > p { margin: 10px 0; }
</style>

<div class="wrap">
        <p>marker,顾名思义,标记的意思,marker标签就是用来给 path、line、polyline 和 polygon 等元素做标记,比如给线头加个小圆点、给线尾加个小箭头、给线的接头处加个任意形状。看下面演示理解一下:</p>
        <p><svg id="svg1" width="600" height="100"></svg></p>
        <p>参考代码:</p>
        <div class="hE"><pre id="pre1"></pre></div>
        <p>本例创建了两个marker标签,标记的宽(markerWidth)、高(markerHeight)一样,因为marker用做标记的实体元素一个是圆,另一个是个三角形,它们的占位尺寸也都是20*20;我们想让标记居中,所以设置的标记与线段的连接点——术语称之为标记参考点即 refX 和 refY——都是取其宽高的一半;每一个marker元素都有自己唯一的id标识符,这是要做标记的元素的引用依据。最后绘制的线条 line 引用了这两个marker标记,通过属性 marker-start(起始点标记)和 marker-end 终结点标记进行引用,赋值使用 url('#id') 函数,支持CSS表达法(上例所用方法),也可以单纯写成svg子元素的属性,像这样:marker-start="url(#id)" marker-end="url(#id)"。</p>
        <p>实体元素引用marker标记还有一个属性,marker-mid,线段中间的标记,但这个标记在上例会无效,因为 marker-mid 属性只在线段的接头处生效,而上例只是一根直线,没有接头的地方。我们来看下一个例子,用小矩形做marker标记,给多边形图案加标记,中间的诸多连接点上的标记都是 marker-mid 给标上的,有多少个连接点就会标上多少个标记(左上角的小矩形是初始样式):</p>
        <p><svg id="svg2" width="600" height="300"></svg></p>
        <p>参考代码:</p>
        <div class="hE"><pre id="pre2"></pre></div>
        <p>留意marker标签的orient参数,它决定了标记的指向,这里我们设置为30,表示旋转30度。如果标记是一个箭头符号,效果显然不行,应把orient设为auto,自动跟随线段的走向旋转。试看下一个在折线上做标记的例子,它两头和里面用椭圆做标记,椭圆会自动跟随线头线尾线的拐点转向(左上角是椭圆的初始样式):</p>
        <p><svg id="svg3" width="600" height="340"></svg></p>
        <p>参考代码:</p>
        <div class="hE"><pre id="pre3"></pre></div>
        <p>marker元素还有两个属性,一是 markerUnits,用来设置坐标系,二是 viewBox,用来定义marker视口。markerUnits缺省时值为 strokeWidth,可选值为 userSpaceOnUse;viewBox 缺省时与实际宽高一致。关于marker标签的宽高这里给个建议:它的宽高设定与里面的元素的宽高最好保持一致,或里面的元素的尺寸不要突破marker元素的宽高设定。</p>
        <p>(注:本文的svg绘制均由 svgdr 插件实时实现,参考代码的生成也由插件实时输出)</p>
</div>

<script>

function loadFile(url) {
        return new Promise((resolve) => {
                var sc = document.createElement('script');
                document.body.appendChild(sc);
            sc.onload = () => resolve(sc);
                sc.src = url;
        });
};

var drFile = 'https://638183.freep.cn/638183/web/js/svgdr.js',
        hlFile = 'https://638183.freep.cn/638183/web/js2024/helight.js';

loadFile(hlFile);
loadFile(drFile).then( () => {
        var dr1 = _dr(svg1);
        dr1.marker('m1_1',20,20,10,10);
        dr1.circle(10,10,10,'green').addTo('m1_1');
        dr1.marker('m1_2',20,20,10,10,'auto');
        dr1.polygon('0 0,0 20,20 10','green').addTo('m1_2');
        dr1.line(20,50,280,50,'red').style('marker-start: url(#m1_1); marker-end: url(#m1_2);');
        pre1.textContent = dr1.code(svg1);
        var dr2 = _dr(svg2);
        dr2.marker('m2',15,15,7.5,7.5,'30');
        dr2.rect(0,0,15,15,'lightgreen').addTo('m2');
        dr2.polygon('200 40,340 140,200 240,100 170,50 50','none','tan').set('marker-start','url(#m2)').set('marker-mid','url(#m2)').set('marker-end','url(#m2)');
        dr2.rect(0,0,15,15,'lightgreen');
        pre2.textContent = dr2.code(svg2);
        var dr3 = _dr('svg3');
        dr3.marker('m3',40,20,20,10,'auto');
        dr3.ellipse(20,10,20,10,'tomato').addTo('m3');
        dr3.polyline('50 50,100 300,300 60,350 280','none', 'tomato').style('marker-start: url(#m3); marker-mid: url(#m3); marker-end: url(#m3);');
        dr3.ellipse(20,10,20,10,'tomato');
        pre3.textContent = dr3.code(svg3);
});
</script>

红影 发表于 2024-10-28 22:20

marker元素就是给单线段端头或多线段中间加标志的吧,orient参数挺好,设置为自动,就可以跟着线段的走向跑了呢,然后用箭头来表示行进方向时就特别清晰。{:4_187:}

红影 发表于 2024-10-28 22:38

<svg id="svg11" width="440" height="100">
        <marker id="shiyan" markerWidth="20" markerHeight="20" refX="10" refY="10" orient="auto">
                <polygon points="0 0,0 20,20 10" fill="green"></polygon>
        </marker>
        <polyline points="20 50,70 50,120 50,170 50,220 50,270 50,320 50,370 50,420 50" fill="none" stroke="tan"style="marker-start: url(#shiyan); marker-mid: url(#shiyan); marker-end: url(#shiyan);"></polyline>
</svg>

红影 发表于 2024-10-28 22:40

加一堆小三角试验一下{:4_173:}

马黑黑 发表于 2024-10-28 23:14

红影 发表于 2024-10-28 22:20
marker元素就是给单线段端头或多线段中间加标志的吧,orient参数挺好,设置为自动,就可以跟着线段的走向跑 ...

{:4_181:}

马黑黑 发表于 2024-10-28 23:14

红影 发表于 2024-10-28 22:40
加一堆小三角试验一下

这是经典用法

红影 发表于 2024-10-28 23:21

马黑黑 发表于 2024-10-28 23:14


谢谢黑黑带来的新的知识{:4_187:}

红影 发表于 2024-10-28 23:21

马黑黑 发表于 2024-10-28 23:14
这是经典用法

我不知道是什么用法,就是试着玩一下{:4_173:}

花飞飞 发表于 2024-10-29 09:53

挺好玩的这些代码,老师讲得好清楚~~每个参数都有详细解说。。。
把路径换成各种图标,再加上标记,那可以有好多种效果。

花飞飞 发表于 2024-10-29 09:53

本帖最后由 花飞飞 于 2024-10-29 09:55 编辑 <br /><br /><svg id="svg5" width="300" height="600">
        <marker id="m4" markerWidth="40" markerHeight="20" refX="20" refY="16" orient="180">
                <ellipse cx="20" cy="10" rx="15" ry="10" fill="IndianRed"></ellipse>
        </marker>
                        <marker id="m5" markerWidth="45" markerHeight="35" refX="7.5" refY="2" orient="auto">
                <rect x="0" y="0" width="45" height="4" fill="OliveDrab"></rect>
        </marker>
        <polyline points="50 40,50 70,50 100,50 130,50 160,50 190,50 220,50 258 " fill="none" stroke-width="1.6" stroke="OliveDrab" style="marker-start: url(#m4); marker-mid: url(#m4); marker-end: url(#m5);"></polyline>

</svg>

花飞飞 发表于 2024-10-29 09:54

把椭圆和矩形结合起来,画一个糖葫芦。{:4_170:}

梦江南 发表于 2024-10-29 10:24

跟着老师学代码。{:4_190:}

马黑黑 发表于 2024-10-29 21:12

梦江南 发表于 2024-10-29 10:24
跟着老师学代码。

{:4_191:}

南无月 发表于 2024-11-1 21:26

我觉得棒棒糖很形像的呀
页: [1]
查看完整版本: svg : marker 标记