(一)用SVG解决实际问题

316 阅读7分钟

前言

不知道你们有没有这种感觉,面试前端工程师的时候,大家千篇一律简历上都是熟悉Vue.js,ElementUI,做的都是XX管理系统,仿佛增删改查成了前端的主旋律,一问你知不知道前端可视化,对SVG了解有多少,最常见的回答就是我没用过,这东西真的有应用场景吗?我的回答是有的,之前做的是一个地铁项目,对方提供给我们一张张CAD图,图上有成千上万的设备,需要对设备的状态有所感知,例如某一个设备掉线了,我能准确地知道哪个设备出问题了,并且画面上能准确知道他的位置。当摄像机故障上报的时候,这个设备要能够出现告警闪烁。

CAD文件是这样的

图片1.png 这只是其中一个站点的例子,这样的数据大概有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 元素的大小。

1685500820314.jpg

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>

image.png

如果我想要把圆形变成红色背景的,应该怎么办呢,这就跟css有明显不一样的地方,css通常会采用background-color,但是SVG元素应该采用


.fancy {
  fill: red;  --对应background
  stroke: green;   --对应border-color
  stroke-width: 3px;  --不写storke-width默认一像素,对应border
}

image.png

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属性表示线段的样式

image.png

4)polyline

<polyline>标签用于绘制一根折线。

<svg width="300" height="180">
  <polyline points="3,3 30,28 3,53" fill="none" stroke="black" />
</svg>

<polyline>points属性指定了每个端点的坐标,横坐标与纵坐标之间与逗号分隔,点与点之间用空格分隔

image.png

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定义垂直轴向的圆角半径

image.png

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属性,指定了椭圆横向轴和纵向轴的半径(单位像素)

image.png

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属性指定了每个端点的坐标,横坐标与纵坐标之间与逗号分隔,点与点之间用空格分隔

image.png

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>

image.png <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的椭圆,并沿着椭圆的逆时针方向绘制。

下面是一些常见的指令:

指令参数描述
Mx y起始点坐标x y (Move to
Lx y从当前点的坐标画直线到指定点的 x y坐标 (Line to
Hx从当前点的坐标画水平直线到指定的x轴坐标 (Horizontal line to
Vy从当前点的座标画垂直直线到指定的y轴坐标 (Vertical line to
Cx1 y1 x2 y2 x y从当前点的坐标画条贝塞尔曲线到指定点的x, y坐标,其中 x1 y1x2, y2为控制点 (Curve
Sx2 y2 x y从当前点的坐标画条反射的贝塞曲线到指定点的x, y坐标,其中x2, y2为反射的控制点(Smooth curve
Qx1 y1 x y从当前点的坐标画条反射二次贝塞曲线到指定点的x, y坐标,其中x1 y1为控制点(Quadratic Bézier curve
Tx y从当前点的坐标画条反射二次贝塞曲线到指定点的x, y坐标,以前一个坐标为反射控制点(Smooth Quadratic Bézier curve
Arx 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)起点的横坐标和纵坐标。文字的样式可以用classstyle属性指定。

设置字体属性:

SVG提供了一些属性,类似于它们的CSS同行,用来激活文本选区。下列每个属性可以被设置为一个SVG属性或者成为一个CSS声明:font-familyfont-stylefont-weightfont-variantfont-stretchfont-sizefont-size-adjustkerningletter-spacingword-spacingtext-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>

image.png

<use>href属性指定所要复制的节点,x属性和y属性是<use>左上角的坐标。另外,还可以指定widthheight坐标

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>

image.png

好了,当你掌握了这些基础知识,你就可以把上述cad图像转换成svg图形了,当然SVG可不止这么些属性,你可以查阅相关资料去拓展自己的知识面