马黑黑 发表于 2024-11-7 07:42

svgdr教程·path路径

<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>path路径</h2>
<div class="art">
        <p>指令:<mark>path()</mark></p>
        <p>参数:<mark>d, fill, stroke, stroke-width, stroke-linecap, stroke-linejoin</mark></p>
        <p>语法:<mark>path(d, fill, stroke, stroke-width, stroke-linecap, stroke-linejoin)</mark></p>
        <p>其中:</p>
        <blockquote>
                ① d - path路径标签的 d 属性,用于描述路径走向,是一系列路径指令加数据的集合,字符型<br>
                ② fill - 填充色,基于路径所包围的区域,缺省时默认用黑色填充,字符型<br>
                ③ stroke - 路径描边色即线条颜色,缺省时路径为透明不可见,字符型<br>
                ④ stroke-width - 路径线条厚度,缺省时默认1(像素),数值<br>
                ⑤ stroke-linecap - 路径起始、终止点线帽样式,字符型,可选值 butt(缺省)、round(圆)、square(方块)<br>
                ⑥ stroke-linejoin - 路径拐角样式,字符型,缺省值 bevel,可选值 miter(斜接)、round(圆)<br>
        </blockquote>
        <p><strong>关于 path 路径 d 属性</strong></p>
        <p><span class="tRed">d</span> 属性是 <span class="tRed">&lt;path&gt;</span> 标签的路径描述,属性值的第一个指令是 M 或 m 表示将画笔移动(move)到某个坐标点,然后根据需要使用相应指令绘制路径。d属性的指令有:</p>
        <blockquote>
                * M(或 m)- 画笔移动到某点,是路径的起始点<br>
                ① L(或 l)- 画直线到 【例】L100 130<br>
                ② H(或 h)- 画水平线到 【例】H240<br>
                ③ V(或 v)- 画垂直线到 【例】V300<br>
                ④ C(或 c)- 画三次贝塞尔曲线,格式为<mark>C 控制点1 控制点2 终点</mark> 【例】C10 10,390 10,390 200<br>
                ⑤ S(或 s)- 紧跟 C(c)或此前的 S(s)指令接着绘制平滑曲线到某点,需要一个控制点+终点坐标 【例】S195 60,320 180<br>
                ⑥ Q(或 q)- 画二次贝塞尔曲线,格式为<mark>Q 控制点 终点</mark> 【例】Q240 -10,300 200<br>
                ⑦ T(或 t)- 紧跟 Q(q)或此前的 Q(q)指令接着绘制平滑曲线到某点,只需提供终点坐标 【例】Q300 100<br>
                ⑧ A(或 a)- 画圆弧,格式为 <mark>X轴半径 Y轴半径 旋转角度 大弧(1)或小弧(0) 顺时针(1)或逆时针(0) 终点X坐标 终点Y坐标</mark> 【例】A 30 50 0 <br>0 1 162.55 162.45
                * Z(或 z)- 路径是否闭合,加在路径描述数据的末尾 【例】M .... Z
        </blockquote>
        <p>以上指令使用大写时称为<span class="tRed">绝对路径</span>,基于SVG坐标系的点坐标;使用小写是称为<span class="tRed">相对路径</span>,表示画笔在上一个点的基础上,例如,假设上一个点坐标为 (20,50),则,<mark>l100 60</mark> 画直线的指令中,100 表示从X坐标点 20 起笔画 100 个像素的距离、从Y坐标点 50 起笔画 60 个像素的距离,结果画笔所在的新的坐标点将是 (120, 110)。</p>
        <p>路径的 d 属性是一个庞杂的学问,svgdr 在绘制路径方面没有对d属性进行指令封装,仅将d作为一个参数使用。路径d属性的设计请自行学习研究,掌握透彻后,世界上将没有什么是d属性描述不出来的——path路径是svg最强大的绘制工具,这一切都归功于d属性。</p>
        <p>下面简单演示一下 path() 指令的应用:</p>
        <svg id="msvg" width="800" height="400"></svg>
        <p>以上图案的 svgdr 绘制代码:</p>
        <div id="div1"><pre id="pre1">
//H,V,L 指令
dr.path('M20 20 H100 V100 L180 20','none','blue',4);//(画折线)
dr.path('M20 120 H180 V200 H20 Z','none','blue',4);//画矩形(z命令令其闭合)
//二次贝塞尔曲线 Q、T 指令
dr.path('M20 220 Q60 400,180 220','none','blue',5);
dr.path('M20 380 Q40 290,100 350 T180 300','none','blue',2);
//三次贝塞尔曲线 C、S指令
var d1 = 'M200 20 C0 200,500 300,600 20',
    d2 = 'M200 200 C250 400,300 30,300 260 S360 300, 600 100';
dr.path(d1,'none','pink',3);
dr.path(d2,'none','teal',3);
//圆弧 A 指令
var d3 = 'M640 100 A50,50,0,0,0,740,100 A50,50,0,0,0,640,100';//画圆
var d4 = 'M540 270 A100,50,0,0,0,740,270 A100,50,0,0,0,540,270';//画椭圆
dr.path(d3,'lightblue');
dr.path(d4,'none','purple',4).style('stroke-dasharray: 4 6');
        </pre></div>
        <p>上面绘制指令生成的SVG代码如下:</p>
        <div id="div2"><pre id="pre2"></pre></div>
        <p>本节的最后是一个用路径绘制多边形的完整代码示例,代码中:</p>
        <blockquote>
                ① 第6行,声明若干变量,其中:tt 是多边形外角总数、r 为半径、angle 为角平均值、d 是d属性字串变量;<br>
                ② 第7 - 16行,用一个for循环按从小到大遍历所有的角,先将角转换成弧度(第8行),再用cos和sin计算出角所在的点坐标值(第9、10行),里面的 200 是svg中心点坐标(加上它是因为SVG坐标起始于左上角);接着,用一个if语句判断循环是否为首次动作,是的话,指令使用 M 带上xy值,否则指令使用 L 带上xy值。这些值的获取均不断加到 d 变量中(<mark>d += ...</mark>);最后,将路径画出来(第17行),注意这里在d变量值基础上加一个 z 表示路径封闭,否则会有缺口,z大小写都是封闭没有区别。<br>
        </blockquote>
        <div id="div3"><pre id="pre3">
&lt;svg id="mysvg" width="400" height="400"&gt;

&lt;script type="module"&gt;
import Dr from 'https://638183.freep.cn/638183/web/mod/svgdr.js';
var dr = Dr.dr('mysvg');
var tt = 8, r = 180, angle = 360 / tt, d = '';
for(var i = 0; i &lt; tt; i ++) {
    var rad = (Math.PI / 180)* i * angle;
    var x = 200 + r * Math.cos(rad),
      y = 200 + r * Math.sin(rad);
    if(i &lt; 1) {
      d += 'M' + x + ' ' + y;
    } else {
      d += ' L' + x + ' ' + y;
    }
}
dr.path(d + 'z','none','gray',8);
&lt;/script&gt;
        </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.path('M20 20 H100 V100 L180 20','none','blue',4);
dr.path('M20 120 H180 V200 H20 Z','none','blue',4);
dr.path('M20 220 Q60 400,180 220','none','blue',5);
dr.path('M20 380 Q40 290,100 350 T180 300','none','blue',2);
var d1 = 'M200 20 C0 200,500 300,600 20',
    d2 = 'M200 200 C250 400,300 30,300 260 S360 300, 600 100';
dr.path(d1,'none','pink',3);
dr.path(d2,'none','teal',3);
var d3 = 'M640 100 A50,50,0,0,0,740,100 A50,50,0,0,0,640,100';
var d4 = 'M540 270 A100,50,0,0,0,740,270 A100,50,0,0,0,540,270';
dr.path(d3,'lightblue');
dr.path(d4,'none','purple',4).style('stroke-dasharray: 4 6');
pre2.textContent = dr.code(msvg);

hl.hl(div1, pre1);
hl.hl(div2, pre2);
hl.hl(div3, pre3);

</script>

梦江南 发表于 2024-11-7 08:05

跟着老师学代码。早上好!{:4_190:}

红影 发表于 2024-11-7 09:24

这个涵盖了所有路径内容,这个太不容易了,黑黑厉害{:4_199:}

红影 发表于 2024-11-7 10:28

正在一个个看,第二个例子的矩形居然被恍了一下
<path d="M20 120 H180 V200 H20 Z"……起点和第一二个设置容易理解,第三个值我竟然以为也是180,忘记了是从上一个点延续下去的,所以最后这条横线当然是遵守从y200的位置,回到M点的x20的位置。嗯嗯,想明白了{:4_173:}
画横线竖线是画位置,不是画长度。其实都是画位置,必须扔掉长度的思维了。嗯嗯,笑话我自己一下{:4_173:}

红影 发表于 2024-11-7 10:31

这个课程太厉害了,有画线还有画两种贝塞尔的还有圆弧的,把路径的种类全包含了。{:4_199:}
路径还要留意需要封闭的时候,用z来解决。

红影 发表于 2024-11-7 10:45

最后的多边形案例也有趣,就用简单的三角函数,就能得到所有的路径点{:4_199:}
不过if(i < 1)这个判断式没怎么看懂。

马黑黑 发表于 2024-11-7 17:47

红影 发表于 2024-11-7 10:45
最后的多边形案例也有趣,就用简单的三角函数,就能得到所有的路径点
不过if(i < 1)这个判断式没 ...

d属性的构成:Mx1,y1 Lx2,y2 Lx3,y3 。。。

第一个是 M,然后才是 L,循环语句中的 if 语句就是处理这个问题:i 步进变量为小于 1 的时候,用 M 带 xy 数值,大于等于 1 的时候用 L 带xy数值

马黑黑 发表于 2024-11-7 17:48

红影 发表于 2024-11-7 10:31
这个课程太厉害了,有画线还有画两种贝塞尔的还有圆弧的,把路径的种类全包含了。
路径还要留意 ...

理解正确

马黑黑 发表于 2024-11-7 17:48

梦江南 发表于 2024-11-7 08:05
跟着老师学代码。早上好!

{:4_191:}

马黑黑 发表于 2024-11-7 17:50

红影 发表于 2024-11-7 10:28
正在一个个看,第二个例子的矩形居然被恍了一下

路径的大写指令用坐标点(x,y)来表示位置,这是绝对位置;小时时,用距离加上一个点的(x,y)值。

花飞飞 发表于 2024-11-7 20:21

从头到尾看过了,一句废话没有,一个多余的标点都没有。
这就是路径教科书。。{:4_173:}

全面又形象,详细还幽默。。
最后还有升级版,发了个多边形制作小工具。。

花飞飞 发表于 2024-11-7 20:26

那个加了S指令的三次贝塞尔曲线,飘逸潇洒。
有时候做贴时需要虚线,还有曲线条,但怎么也找不到合适的
如果能先设计好,再截下来使用,那可美S了。。
暂时做不到的时候,可以先想想……{:4_173:}

马黑黑 发表于 2024-11-7 21:35

花飞飞 发表于 2024-11-7 20:26
那个加了S指令的三次贝塞尔曲线,飘逸潇洒。
有时候做贴时需要虚线,还有曲线条,但怎么也找不到合适的
...

svg还是很实用的

马黑黑 发表于 2024-11-7 21:36

花飞飞 发表于 2024-11-7 20:21
从头到尾看过了,一句废话没有,一个多余的标点都没有。
这就是路径教科书。。



{:4_205:}

红影 发表于 2024-11-7 23:21

马黑黑 发表于 2024-11-7 17:47
d属性的构成:Mx1,y1 Lx2,y2 Lx3,y3 。。。

第一个是 M,然后才是 L,循环语句中的 if 语句就是处理这 ...

原来M和L是这个意思,现在知道它们的意思了{:4_187:}

红影 发表于 2024-11-7 23:22

马黑黑 发表于 2024-11-7 17:48
理解正确

这个路径也是可以有无限可能性。

红影 发表于 2024-11-7 23:23

马黑黑 发表于 2024-11-7 17:50
路径的大写指令用坐标点(x,y)来表示位置,这是绝对位置;小时时,用距离加上一个点的(x,y)值。

哦,我应该是把两者也弄混了,不过现在明白了{:4_187:}

马黑黑 发表于 2024-11-7 23:46

红影 发表于 2024-11-7 23:23
哦,我应该是把两者也弄混了,不过现在明白了

{:4_190:}

马黑黑 发表于 2024-11-7 23:47

红影 发表于 2024-11-7 23:22
这个路径也是可以有无限可能性。

path才是svg最强大的绘制工具

马黑黑 发表于 2024-11-7 23:47

红影 发表于 2024-11-7 23:21
原来M和L是这个意思,现在知道它们的意思了

路径的绘制,有一整套语法,都是根据路径指令来的
页: [1] 2 3 4
查看完整版本: svgdr教程·path路径