提到SVG大家一定都不陌生,那svg中path有了解过么,知道其中的参数都是什么含义么?如果你已经知道了,那不妨再看一遍熟悉一下,如果不知道那就可以继续阅读一起来学习一下。
什么是SVG
- SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
- SVG 用来定义用于网络的基于矢量的图形
- SVG 使用 XML 格式定义图形
- SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失
- SVG 是万维网联盟的标准
- SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体
通过path绘制图形
path
<path>
是SVG中最常见的形状,可以通过它来绘制矩形、圆形、椭圆、折线等形状。
path
元素的形状是通过属性d
来定义的。d
的值是一系列命令+坐标的
的值组成的。
每一个命令都是用字母来表示的,命令大致可以分为两类
直线命令
-
M = moveto 默认的绘制图形的起始点,
M 10 0
画笔落在x=10,y=0的坐标点,也就是图形的绘制起始点 -
L = lineto 从上一个点到这个点绘制直线,
M 10 0 L 20 30
从(10,0)到(20,30)绘制一条直线) -
H = horizontal lineto 从绘制一条水平线,在x轴上移动,
Hn
代表在x轴上移动到n
的位置M 10 0 H 20
以(10,0)为起始点绘制一条水平线,那么此时结束点的坐标应该为(20,0) -
V = vertical lineto 从上个点开始绘制一条垂直线
M 10 10 V 20
以(10,10)为起始点绘制一条水平线,那么此时结束点的坐标应该为(10,20)
曲线命令
- C = curveto 三次贝塞尔曲线
C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy)
scss
其中(x,y)表示曲线的终点,另外两个是坐标的控制点。
(x1,y1)是起点控制点,(x2,y2)是重点控制点。
控制点描述的是曲线起始点的斜率,是从起点到重点的渐变过程。
- S = smooth curveto 延长三次贝塞尔曲线
S x2 y2, x y (or s dx2 dy2, dx dy)
go
S用来创建与前面一样的贝塞尔曲线。
如果 `S` 命令跟在一个 `C` 或 `S` 命令后面,则它的第一个控制点会被假设成前一个命令曲线的第二个控制点的中心对称点。
如果 `S` 命令单独使用,前面没有 `C` 或 `S` 命令,那当前点将作为第一个控制点。
- Q = quadratic Bézier curve 二次贝塞尔曲线
Q x1 y1, x y (or q dx1 dy1, dx dy)
scss
同C曲线类似,其中(x,y)表示曲线的终点,(x1,y1)是控制点
- T = smooth quadratic Bézier curveto 延长二次贝塞尔曲线
T x y (or t dx dy)
r
同S类似,会通过前一个控制点,推断出一个新的控制点。T前面必须是一个Q或T命令,如果T单独使用,则画出直线
- A = elliptical Arc 弧形命令
css
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy
- Z = closepath 闭合路径,不区分大小写
无论是直线命令还是曲线命令,都会有两种表示方式,一种是大写字母,采用的是绝对定位 ,另一种是小写字母,采用的是相对定位,即从上一个点开始,像x轴或y轴移动,例如:如下图所示,三个红色圆点的左边分别是(10,10),(10,20),(10,30)
M 10 10 V 20
是以(10,10)为起始点绘制一条水平线,那么此时结束点的坐标应该为(10,20);
M 10 10 v 20
是以(10,10)为起始点沿着y轴移动10个像素,结束点就是(10,30)
内置的一些便捷图形
path
命令相对来说比较自由,可以画出自己想要的图形,但是如果只是画直线,圆形椭圆,SVG是有一些内置便捷图形可以使用的
矩形< rect >
ini
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect width="300" height="100"
style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)"/>
</svg>
圆形 < circle >
ini
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="40" stroke="black"
stroke-width="2" fill="red"/>
</svg>
椭圆< ellipse >
ini
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<ellipse cx="300" cy="80" rx="100" ry="50"
style="fill:yellow;stroke:purple;stroke-width:2"/>
</svg>
直线< line >
ini
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<line x1="0" y1="0" x2="200" y2="200"
style="stroke:rgb(255,0,0);stroke-width:2"/>
</svg>
多边形< polygon >
ini
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<polygon points="200,10 250,190 160,210"
style="fill:lime;stroke:purple;stroke-width:1"/>
</svg>
文本 < text >
ini
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<text x="0" y="15" fill="red">I love SVG</text>
</svg>
SVG优势
与其他格式相比,使用SVG的优势在于:
- SVG 可被非常多的工具读取和修改(比如记事本)
- SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
- SVG 是可伸缩的
- SVG 图像可在任何的分辨率下被高质量地打印
- SVG 可在图像质量不下降的情况下被放大
- SVG 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
- SVG 可以与 Java 技术一起运行
- SVG 是开放的标准
- SVG 文件是纯粹的 XML
结束语
看了SVG的命令,在联想到我们日常使用的时候,可能大多数是用于一些图标类的地方,但是如果是图标都会有UI同学帮忙设计,再直接导出svg就行,我们无需关系svg中命令是怎么样的,那为什么还要知道呢?
最初我也是这么觉得的,直到最近使用antv G6做了一个树形图,要绘制如下图的折线,这些折线的path就是同svg中的path命令是一样的。所以就有了学习SVG命令的想法,也就有了这篇文章。
最后附上折线的路径代码
arduino
G6.registerEdge('flow-line', {
draw(cfg, group) {
const startPoint = cfg.startPoint;
const endPoint = cfg.endPoint;
const {style} = cfg;
const shape = group.addShape('path', {
attrs: {
stroke: style.stroke,
path: [
['M', startPoint.x, startPoint.y], // 起始位置是上一个节点的可以连接的结束点
['L', (endPoint.x - startPoint.x) / 2 + startPoint.x, startPoint.y], // 结束位置到开始位置中间点
['L', (endPoint.x - startPoint.x) / 2 + startPoint.x, endPoint.y], // 三分之一处
['L', endPoint.x, endPoint.y], // 起始位置是后一个节点的可以连接的起始点
],
},
});
return shape;
},
});