前言
不知道你们有没有这种感觉,面试前端工程师的时候,大家千篇一律简历上都是熟悉Vue.js,ElementUI,做的都是XX管理系统,仿佛增删改查成了前端的主旋律,一问你知不知道前端可视化,对SVG了解有多少,最常见的回答就是我没用过,这东西真的有应用场景吗?我的回答是有的,之前做的是一个地铁项目,对方提供给我们一张张CAD图,图上有成千上万的设备,需要对设备的状态有所感知,例如某一个设备掉线了,我能准确地知道哪个设备出问题了,并且画面上能准确知道他的位置。当摄像机故障上报的时候,这个设备要能够出现告警闪烁。
CAD文件是这样的
这只是其中一个站点的例子,这样的数据大概有2万个左右,如果是你,接到这种需求你会怎么实现?这就需要你对SVG这种可视化得到技术有足够的了解。
第一章 SVG基础知识
要解决这个问题,首先要对SVG基础知识有足够的了解。首先来理解几个概念
1)viewbox
可以理解为SVG画布,也可以理解为舞台,所有SVG图形都是在画布上展示的,相当于可视区,如果你画的图形超出了viewbox的可视区,那么将不会被展示。 用法如下:
<svg width="100" height="100" viewBox="50 50 50 50">
<circle id="mycircle" cx="50" cy="50" r="50" />
</svg>
<viewBox>属性的值有四个数字,分别是左上角的横坐标和纵坐标、视口的宽度和高度。上面代码中,SVG 图像是100像素宽 x 100像素高,viewBox属性指定视口从(50, 50)这个点开始。所以,实际看到的是右下角的四分之一圆。
注意,视口必须适配所在的空间。上面代码中,视口的大小是 50 x 50,由于 SVG 图像的大小是 100 x 100,所以视口会放大去适配 SVG 图像的大小,即放大了四倍。
如果不指定width属性和height属性,只指定viewBox属性,则相当于只给定 SVG 图像的长宽比。这时,SVG 图像的默认大小将等于所在的 HTML 元素的大小。
2)circle
<circle>标签代表圆形
<svg width="300" height="180">
<circle cx="30" cy="50" r="25" />
<circle cx="90" cy="50" r="25" class="red" />
<circle cx="150" cy="50" r="25" class="fancy" />
</svg>
如果我想要把圆形变成红色背景的,应该怎么办呢,这就跟css有明显不一样的地方,css通常会采用background-color,但是SVG元素应该采用
.fancy {
fill: red; --对应background
stroke: green; --对应border-color
stroke-width: 3px; --不写storke-width默认一像素,对应border
}
3)line
<line>标签用来绘制直线。
<svg width="300" height="180">
<line x1="0" y1="0" x2="200" y2="0" style="stroke:rgb(0,0,0);stroke-width:5" />
</svg>
上面代码中,<line>标签的x1属性和y1属性,表示线段起点的横坐标和纵坐标;x2属性和y2属性,表示线段终点的横坐标和纵坐标;style属性表示线段的样式
4)polyline
<polyline>标签用于绘制一根折线。
<svg width="300" height="180">
<polyline points="3,3 30,28 3,53" fill="none" stroke="black" />
</svg>
<polyline>的points属性指定了每个端点的坐标,横坐标与纵坐标之间与逗号分隔,点与点之间用空格分隔
4)rect
<rect>标签用于绘制矩形
<svg width="300" height="180">
<rect x="0" y="0" height="100" width="200" rx="10" ry="10" style="stroke: #70d5dd; fill: #dd524b" />
</svg>
<rect>的x属性和y属性,指定了矩形左上角端点的横坐标和纵坐标;width属性和height属性指定了矩形的宽度和高度(单位像素)。
rx 和 ry 属性可以创建圆角矩形,rx定义水平轴向的圆角半径,ry定义垂直轴向的圆角半径
5)ellipse
<ellipse>标签用于绘制椭圆
<svg width="300" height="180">
<ellipse cx="60" cy="60" ry="40" rx="20" stroke="black" stroke-width="5" fill="silver"/>
</svg>
llipse>的cx属性和cy属性,指定了椭圆中心的横坐标和纵坐标(单位像素);rx属性和ry属性,指定了椭圆横向轴和纵向轴的半径(单位像素)
6)polygon
<polygon>标签用于绘制多边形,和polyline的区别是这个图形是闭合的
<svg width="300" height="180">
<polygon fill="green" stroke="orange" stroke-width="1" points="0,0 100,0 100,100 0,100 0,0"/>
</svg>
<polygon>的points属性指定了每个端点的坐标,横坐标与纵坐标之间与逗号分隔,点与点之间用空格分隔
7)path
<path>标签用于制路径
<svg width="90" height="90">
<path d="
M 18,3
L 46,3
L 46,40
L 61,40
L 32,68
L 3,40
L 18,40
Z
" fill="blue" />
</svg>
<svg width="90" height="90">
<path d="
M60,30
a30,30 0 0,1 0,60
L0,90 0,30
a30,30 0 0,1 60,0" fill="red" />
</svg>
<svg width="90" height="90">
<path d="
M75,45
a30,30 0 0,1 -60,0
a30,30 0 0,1 60,0" stroke-width="1" stroke="blue" fill="none"/>
</svg>
<path>的d属性表示绘制顺序,它的值是一个长字符串,每个字母表示一个绘制动作,后面跟着坐标
字母含义:
- M:移动到(moveto)
- L:画直线到(lineto)
- Z:闭合路径
- A:弧形
- C:贝塞尔曲线
解释一下 a30,30 0 0,1 -60,0
- a:表示使用相对坐标值进行绘制。
- 30,30:表示椭圆的长轴半径和短轴半径分别为30。
- 0:表示椭圆的旋转角度为0度。
- 0,0:表示弧线段的起点与当前位置的相对坐标值都为0,即不改变位置。
- 1:表示绘制逆时针方向的弧线段。
- 0,60:表示沿y轴方向绘制一个长度为60的弧线段。 因此,这条路径会从当前位置开始,在纵向上绘制一个长度为60、高度为60的椭圆,并沿着椭圆的逆时针方向绘制。
下面是一些常见的指令:
| 指令 | 参数 | 描述 |
|---|---|---|
M | x y | 起始点坐标x y (Move to) |
L | x y | 从当前点的坐标画直线到指定点的 x y坐标 (Line to) |
H | x | 从当前点的坐标画水平直线到指定的x轴坐标 (Horizontal line to) |
V | y | 从当前点的座标画垂直直线到指定的y轴坐标 (Vertical line to) |
C | x1 y1 x2 y2 x y | 从当前点的坐标画条贝塞尔曲线到指定点的x, y坐标,其中 x1 y1及x2, y2为控制点 (Curve) |
S | x2 y2 x y | 从当前点的坐标画条反射的贝塞曲线到指定点的x, y坐标,其中x2, y2为反射的控制点(Smooth curve) |
Q | x1 y1 x y | 从当前点的坐标画条反射二次贝塞曲线到指定点的x, y坐标,其中x1 y1为控制点(Quadratic Bézier curve) |
T | x y | 从当前点的坐标画条反射二次贝塞曲线到指定点的x, y坐标,以前一个坐标为反射控制点(Smooth Quadratic Bézier curve) |
A | rx ry x-axis-rotation large-arc-flag sweep-flag x y | 从当前点的坐标画个椭圆形到指定点的x, y坐标,其中rx, ry为椭圆形的x轴及y轴的半径,x-axis-rotation是弧线与x轴的旋转角度,large-arc-flag则设定1最大角度的弧线或是0最小角度的弧线,sweep-flag设定方向为1顺时针方向或0逆时针方向(Arc) |
Z | 关闭路径,将当前点坐标与第一个点的坐标连接起来(Closepath) |
8)text
<text>标签用于绘制文本
<text x="10" y="20" style="fill:red;" font-weight="bold">Several lines:
<tspan x="24" y="45">First line.</tspan>
<tspan x="24" y="70">Second line.</tspan>
</text>
</svg>
<text>的x属性和y属性,表示文本区块基线(baseline)起点的横坐标和纵坐标。文字的样式可以用class或style属性指定。
设置字体属性:
SVG提供了一些属性,类似于它们的CSS同行,用来激活文本选区。下列每个属性可以被设置为一个SVG属性或者成为一个CSS声明:font-family、font-style、font-weight、font-variant、font-stretch、font-size、font-size-adjust、kerning、letter-spacing、word-spacing和text-decoration。
文本相关的元素:
tspan: 用来标记大块文本的子部分,它必须是一个text元素或别的tspan元素的子元素。tref: 允许引用已经定义的文本,高效地把它复制到当前位置。你可以使用xlink:href属性,把它指向一个元素,取得其文本内容。你可以独立于源样式化它、修改它的外观。textPath: 该元素利用它的xlink:href属性取得一个任意路径,把字符对齐到路径,于是字体会环绕路径、顺着路径走。
9)image
<image>标签用于插入图片文件。
<svg viewBox="0 0 100 100" width="100" height="100">
<image xlink:href="path/to/image.jpg"
width="50%" height="50%"/>
</svg>
上面代码中,<image>的xlink:href属性表示图像的来源
10)use 标签
use标签用于复制一个图形
<svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg" width="300" height="100">
<circle id="myCircle" cx="5" cy="5" r="4"/>
<use href="#myCircle" x="10" y="0" fill="blue" />
<use href="#myCircle" x="20" y="0" fill="white" stroke="blue" />
</svg>
<use>的href属性指定所要复制的节点,x属性和y属性是<use>左上角的坐标。另外,还可以指定width和height坐标
11) g组
<g>标签用于将多个形状组成一个组(group),方便复用
<svg width="300" height="100">
<g id="myCircle">
<text x="25" y="20">圆形</text>
<circle cx="50" cy="50" r="20"/>
</g>
<use href="#myCircle" x="100" y="0" fill="blue" />
<use href="#myCircle" x="200" y="0" fill="white" stroke="blue" />
</svg>
好了,当你掌握了这些基础知识,你就可以把上述cad图像转换成svg图形了,当然SVG可不止这么些属性,你可以查阅相关资料去拓展自己的知识面