svgdr教程·画折线
本帖最后由 马黑黑 于 2024-11-5 08:10 编辑 <br /><br /><style>.art > p { margin: 12px 0; font: normal 18px/24px sans-serif; }
.art mark { padding: 2px 6px; background: lightblue; }
.art svg { outline: 1px solid silver; }
.tRed { color: red; }
</style>
<h2>画折线</h2>
<div class="art">
<p>指令:<mark>polyline()</mark></p>
<p>参数:<mark>points, fill, stroke, stroke-width, stroke-linecap, stroke-linejoin</mark></p>
<p>语法:<mark>polyline(points, fill, stroke, stroke-width, stroke-linecap, stroke-linejoin)</mark></p>
<p>其中:</p>
<blockquote>
① points - 折线各转角XY坐标集合(字符型),例如:'x1 y1, x2 y2, x3 y3, ..., xn yn'<br>
② fill - 填充色,颜色值(字符型)<br>
③stroke - 描边色,颜色值(字符型)<br>
④ stroke-width - 描边线厚度,数值<br>
⑤ stroke-linecap 折线起始端点线帽样式,字符型,可选值 butt(缺省)、round(圆)、square(方块)<br>
⑥ stroke-linejoin - 折线转角处<span class="tRed">描边</span>形状,字符型,缺省值 bevel,可选值 miter(斜接)、round(圆)<br>
* <span class="tRed">数值可以不用引号,字符型需要使用引号,百分比视为字符型</span>
</blockquote>
<p>参数一 points 是折线端点和各个转角基于svg画布坐标系的XY坐标值,和多边形polygon一样,也是一个点坐标值的组合,字符型;参数二、三、四好理解,分别是填充、描边、描边线厚度。关于填充,由于折线可能有交叉区域,因此填充规则即<mark>fill-rule</mark> 值得注意,尤其是当交叉区域很复杂的时候。fill-rule 属性没有纳入 svgdr 指令 polyline() 的参数,需要时可用<mark>set('fill-rule', 'nonzero | evenodd')</mark>指令或<mark>style('fill-rule: nonzero | evenodd')</mark>指令补充,其中第一个可选值 nonzero 是缺省值;参数五 stroke-linecap 是折线线头、线尾的线帽,可选值 butt(词意是烟蒂,缺省)、round(圆角)、square(方块),其中,从形态上讲,butt和square外观一致,前者不增加线段长度、后者反之;参数六 stroke-linejoin 是描边转角处的样式,常用可选值有 miter(斜接,即尖角缺省值),bevel(斜切)和 round(圆角)。需要注意的是,线帽和折角的样式设置,只有在设置了描边(stroke)前提下才会生效,描边厚度(stroke-width)值越大端点和转角样式的效果越明显。</p>
<svg id="msvg" width="800" height="400"></svg>
<p>以上图案的 svgdr 绘制代码:</p>
<div id="div1"><pre id="pre1">
dr.polyline('100 20,180 180,20 180'); //只有一个 points 参数(默认自动用黑色填充)
dr.polyline('100 220,180 380,20 380', 'none', 'teal', 16); //缺省线帽 butt 不改变线长
dr.polyline('300 20,380 180,220 180', 'none', 'teal', 16, 'square'); //线帽 square 改变线长
dr.polyline('300 220,380 380,220 380', 'none', 'teal', 16, 'round'); //线帽 round 改变线长
dr.polyline('500 20,580 180,420 180', 'none', 'teal', 16, 'round', 'round'); //圆线帽、圆转角
//画一个复杂一点的折线
let pts = '420 380,780 380,780 360, 420 360,420 340,780 340,780 320,420 320,420 300,780 300,780 280,420 280,420 260,780 260,780 240,420 240,420 220,780 220,650 20,650 200,780 20';
dr.polyline(pts, 'none', 'plum', 4);
</pre></div>
<p>上面绘制指令生成的SVG代码如下:</p>
<div id="div2"><pre id="pre2"></pre></div>
<p>最后来看一个用 svgdr 绘制组合图案的代码示范:</p>
<div id="div3"><pre id="pre3">
<svg id="polyline" width="200" height="200" viewBox="-100 -100 200 200"></svg>
<script type="module">
import draw from 'https://638183.freep.cn/638183/web/mod/svgdr.js';
var dr = draw.dr(svg1);
var tt = 12;
for(var i = 0; i < tt; i ++) {
dr.polyline('0 0,70 0,70 -10,85 0,70 10,70 0', 'lightgreen', 'green', 3).transform(`rotate(${360/tt*i}) translate(6)`);
}
</script>
</pre></div>
<p>上面代码可以存为本地 .html 文档并使用浏览器打开,或将代码拿到 <a href="http://mhh.52qingyin.cn/api/pcode/">pencil code</a> 运行。</p>
<p><a href="/forum.php?mod=viewthread&tid=79137&extra=page%3D1" targete="_blank">返回目录</a></p>
</div>
<script type="module">
import hl from 'https://638183.freep.cn/638183/web/mod/helight.js';
import draw from 'https://638183.freep.cn/638183/web/mod/svgdr.js';
var dr = draw.dr('msvg');
dr.polyline('100 20,180 180,20 180');
dr.polyline('100 220,180 380,20 380', 'none', 'teal', 16); //缺省线帽 butt 不改变线长
dr.polyline('300 20,380 180,220 180', 'none', 'teal', 16, 'square'); //线帽 square 改变线长
dr.polyline('300 220,380 380,220 380', 'none', 'teal', 16, 'round'); //线帽 round 改变线长
dr.polyline('500 20,580 180,420 180', 'none', 'teal', 16, 'round', 'round'); //圆线帽、圆转角
//画一个复杂一点的折线
let pts = '420 380,780 380,780 360, 420 360,420 340,780 340,780 320,420 320,420 300,780 300,780 280,420 280,420 260,780 260,780 240,420 240,420 220,780 220,650 20,650 200,780 20';
dr.polyline(pts, 'none', 'plum', 4);
pre2.textContent = dr.code(msvg);
hl.hl(div1, pre1);
hl.hl(div2, pre2);
hl.hl(div3, pre3);
</script>
跟着老师学代码,谢谢老师辛苦!{:4_187:} 去试了一下最后的组合图案,比三套车里的还有趣,线条顶端接的是小三角呢{:4_173:}
<br>
<svg id="zhexian" width="200" height="200" xmlns="http://www.w3.org/2000/svg" viewBox="-100 -100 200 200"></svg>
<script type="module">
import draw from 'https://638183.freep.cn/638183/web/mod/svgdr.js';
var dr1 = draw.dr(zhexian);
var tt = 12;
for(var i = 0; i < tt; i ++) {
dr1.polyline('0 0,70 0,70 -10,85 0,70 10,70 0', 'lightgreen', 'green', 3).transform(`rotate(${360/tt*i}) translate(6)`);
}
</script>
这个跟前几个相比,多了线头、线尾的线帽,以及描边转角样式,而且填充更复杂些。
用案例中的“复杂一点的折线”去填充,发现就很奇特。
<br>
<svg id="msvg11" width="800" height="400" viewBox="300 0 800 400">
<polyline points="420 380,780 380,780 360, 420 360,420 340,780 340,780 320,420 320,420 300,780 300,780 280,420 280,420 260,780 260,780 240,420 240,420 220,780 220,650 20,650 200,780 20" fill="green" stroke="plum" stroke-width="4"></polyline>
</svg>
好像能形成前后线条构成封闭的才被填充,这个比较难预判了。
那个组合图案里的小三角因为闭合了,才被填充了的吧? 案例里的比较复杂的折线那里为什么用let pts =,然后dr.polyline(pts, 'none', 'plum', 4);,不能像其他折线那样直接写么?或者是为了提供一种单独写的方式给大家学习的吧? 和多边形比起来,这个最后不是自动封闭的,如果要回到起点,还需要最后把起点再写上去{:4_187:} dr.polyline('100 20,180 180,20 180'); //只有一个 points 参数(默认自动用黑色填充)
这里混进来一个黑三角,看上去最不像折线了。。
啥参数都不给,只能按三个点的范围圈个地儿。。的节奏{:4_173:} 红影 发表于 2024-11-5 16:40
去试了一下最后的组合图案,比三套车里的还有趣,线条顶端接的是小三角呢
{:4_196:}猪比特之箭 梦江南 发表于 2024-11-5 08:11
跟着老师学代码,谢谢老师辛苦!
{:4_190:} 那个复杂一点的折线,感觉地方够的话可以绘出个斑马线的样纸。。。。
旋转的单图形成的组合图案,更是复杂又漂亮~~
教程知识结构和逻辑层次以及效果,尽显美感。。
这套教程就是独一无二的好贴。。{:4_199:} 红影 发表于 2024-11-5 16:59
这个跟前几个相比,多了线头、线尾的线帽,以及描边转角样式,而且填充更复杂些。
用案例中的“复杂一点的 ...
这里面有着复杂的内区域和外区域分界,fill-rule的取值效果在更复杂交叉的图案中能够体现出来 红影 发表于 2024-11-5 17:01
好像能形成前后线条构成封闭的才被填充,这个比较难预判了。
那个组合图案里的小三角因为闭合了,才被填充 ...
参考资料:https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/fill-rule 红影 发表于 2024-11-5 17:03
案例里的比较复杂的折线那里为什么用let pts =,然后dr.polyline(pts, 'none', 'plum', 4);,不能像其他折 ...
都可以直接写,不过一般的建议是,当值较长,声明一个变量会更好:逻辑上更清晰,修改更容易。 按道理未封闭的线是不被填充的,现在居然可以,且填充部位在意料之外,也是奇特。。 红影 发表于 2024-11-5 17:04
和多边形比起来,这个最后不是自动封闭的,如果要回到起点,还需要最后把起点再写上去
不过请留意,如果折线能够包围区域,默认可以 fill,这意味着它也具备自封闭能力 花飞飞 发表于 2024-11-5 19:16
dr.polyline('100 20,180 180,20 180'); //只有一个 points 参数(默认自动用黑色填充)
这里混进来一个黑 ...
你多几个点就不是三角形了 花飞飞 发表于 2024-11-5 19:23
那个复杂一点的折线,感觉地方够的话可以绘出个斑马线的样纸。。。。
旋转的单图形成的组合图案,更是复杂 ...
俺这个 svgdr 本身就是独一无二的,没人这么弄 花飞飞 发表于 2024-11-5 19:27
按道理未封闭的线是不被填充的,现在居然可以,且填充部位在意料之外,也是奇特。。
只要不禁止fill,折线也是自动封闭的 马黑黑 发表于 2024-11-5 19:28
你多几个点就不是三角形了
{:4_173:}嗯哪,只能说如果不给线型的话,这几个点就是界碑,圈地儿用的