引言
在上一篇中我们提到了,流程图库的实现技术方案中主要有 SVG 和 Canvas,为了方便后续的学习,这一章我们将带大家学习一下 SVG 相关的知识,并着重介绍下在流程图库中可能用到的一些技术点,并用原生的 SVG 绘制一个原始概念上的流程图。本章不会涉及太多的拓展知识,如果大家对 SVG 感兴趣,可以通过大漠老师的 《深入浅出 SVG》课程深入学习。
什么是 SVG
可缩放矢量图形(Scalable Vector Graphics, SVG)基于 XML 标记语言,用于描述二维的矢量图形。
首先,援引 MDN 文档中对于 SVG 的解释,看不太懂吧 o.0。那我们用通俗的语言解释一下,SVG 是一种用来绘制图形的格式,简单来说,它就是一种基于代码的图片。可以把它理解为用文字描述图形的方式。
比如,我们通常见的图片(如 JPEG 或 PNG)是由像素点组成的,所以当你放大这些图片时,图像会模糊,因为它是用无数的小点拼起来的。而 SVG 不同,它是用数学公式来描述图形的,比如说”这里画一个圆、那边画一个方块“,所以无论怎样放大缩小,它都不会失真,图像始终保持清晰。
SVG 文件就像网页里的代码一样,可以直接嵌入到网页中,并且你可以用代码去修改它,比如改变颜色、形状,甚至加上交互功能(点击、拖动等)。所以它特别适合那些需要放大缩小、精确显示的图形,比如流程图、图标或者一些网页上的小动画。
SVG 的语法介绍
基本结构
SVG 文件或元素的基本结构如下:
<!-- 示例代码 -->
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<!-- 图形元素 -->
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
xmlns="http://www.w3.org/2000/svg"
: 这是SVG 的命名空间,告诉浏览器这是一个 SVG 文件width
和height
:制定了 SVG 画布的宽度和高度- 在
<svg>
标签中,我们可以插入各种图形元素,如矩形、圆形、线条等(上面我们插入了一个圆形)
概念介绍
常见元素
<rect>
:绘制矩形<circle>
:绘制圆形<line>
:绘制直线<text>
:绘制文本<path>
:路径,绘制复杂图形
常见属性
fill
:填充颜色stroke
:边框颜色stroke-width
:边框宽度
嵌入方式
如何在 HTML 中嵌入 SVG,可以直接嵌入 SVG 代码,即直接将 svg 元素写在 HTML中;也可以通过 <img>
标签使用,如下所示:
<img src="image.svg" alt="Description of the image" width="300" height="200" />
src="image.svg"
:指定 SVG 文件的路径,可以是本地文件路径或外部 URL。alt="..."
:为 SVG 图像提供替代文本,提升无障碍性,特别是在图像无法加载时显示该文本。width
和height
:指定图像的宽度和高度,SVG 图像可以无损缩放,因此指定任意大小图像仍然保持清晰。
使用 SVG 绘制一个流程图
了解上面的基础概念后,我们直接上手撸一个简单的流程图,主要包括以下这些元素:
- 开始节点(圆形)
- 处理步骤(矩形)
- 判断条件(菱形)
- 连接这些形状的线条
1. 创建一个流程图画布
首先,定义一个 400x300 大小的 SVG 画布:
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300">
<!-- 图形内容将在这里绘制 -->
</svg>
2. 添加开始节点(圆形)
使用 <circle>
标签来绘制一个圆形,表示流程的开始节点。cx 和 cy 定义圆心的坐标,r 定义半径,fill 定义填充颜色。
<circle cx="50" cy="50" r="30" fill="lightblue" stroke="black" stroke-width="2"/>
<text x="50" y="55" font-size="16" text-anchor="middle" fill="black">开始</text>
说明:
- 圆心坐标为 (50, 50),半径为 30
fill="lightblue"
表示圆的填充颜色为浅蓝色,stroke=“black" 表示边框色为黑色- 使用
<text>
元素在圆的中间添加 "开始" 文字
3. 添加处理步骤(矩形)
使用 <rect>
标签绘制矩形表示处理步骤,并添加对应的文字说明。
<rect x="130" y="35" width="100" height="30" fill="lightgreen" stroke="black" stroke-width="2"/>
<text x="180" y="55" font-size="16" text-anchor="middle" fill="black">处理</text>
说明:
- 矩形的左上角坐标为 (150, 35),宽度为 100,高度为 30
- 矩形内的文本内容为“处理”
4. 添加判断条件
菱形可以通过旋转矩形来实现,用 <polygon>
标签绘制。
<polygon points="300,30 330,50 300,70 270,50" fill="lightyellow" stroke="black" stroke-width="2"/>
<text x="300" y="55" font-size="16" text-anchor="middle" fill="black">判断</text>
说明:
- points 定义了菱形的四个顶点坐标
- 菱形内添加了“判断”文字
5. 添加连线
使用 <line>
标签绘制连接不同流程步骤的线条。
<line x1="80" y1="50" x2="130" y2="50" stroke="black" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="230" y1="50" x2="270" y2="50" stroke="black" stroke-width="2" marker-end="url(#arrow)"/>
说明:
x1
,y1
和x2
,y2
分别是线段的起点和终点坐标stroke="black"
表示线条颜色为黑色
为了在连线的末端加上箭头,我们需要定义一个箭头标记:
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="5" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="black"/>
</marker>
</defs>
这个箭头会在流程图的连线上自动显示
6. 完整代码
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="300">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="5" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L5,3 z" fill="black"/>
</marker>
</defs>
<!-- 开始节点 -->
<circle cx="50" cy="50" r="30" fill="lightblue" stroke="black" stroke-width="2"/>
<text x="50" y="55" font-size="16" text-anchor="middle" fill="black">开始</text>
<!-- 处理步骤 -->
<rect x="130" y="35" width="100" height="30" fill="lightgreen" stroke="black" stroke-width="2"/>
<text x="180" y="55" font-size="16" text-anchor="middle" fill="black">处理</text>
<!-- 判断条件 -->
<polygon points="300,30 330,50 300,70 270,50" fill="lightyellow" stroke="black" stroke-width="2"/>
<text x="300" y="55" font-size="16" text-anchor="middle" fill="black">判断</text>
<!-- 连线 -->
<line x1="80" y1="50" x2="130" y2="50" stroke="black" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="230" y1="50" x2="270" y2="50" stroke="black" stroke-width="2" marker-end="url(#arrow)"/>
</svg>
效果图如下:
其它一些常用知识点
使用路径绘制复杂图形
SVG 的 <path>
元素是用于绘制复杂形状的强大工具。通过一个 d 属性定义路径数据,可以精确地描述线条、曲线和其它复杂几何形状。它是 SVG 中最灵活、最强大的绘图元素
1. 基本结构
一个<path>
元素的基本语法如下:
<path d="M10 10 H 90 V90 H 10 Z" fill="none" stroke="black" />
说明:
- d 属性: 包含路径数据的字符串,定义路径的形状
- stroke 属性:设置路径的描边颜色
- fill 属性:设置路径内部的填充颜色
2. d 属性指令介绍
d 属性由一系列命令和参数组成。以下是一些常见的命令:
(1) 直线相关
-
M x y (Move To)
移动到自定坐标点 (x, y),不绘制线条- 绝对坐标:M(大写)
- 相对坐标:m(小写)
-
L x y (Line To)
从当前点绘制一条直线到 (x, y)- 绝对:L
- 相对:l
-
H x / V y
- H:水平直线到指定的 x 坐标。
- V:垂直直线到指定的 y 坐标
(2) 曲线相关
-
C x1 y1, x2 y2, x y (Cubic Bezier Curve)
绘制三次贝塞尔曲线,控制点为 (x1, y1) 和 (x2, y2),终点为 (x, y)。 -
S x2 y2, x y (Smooth Cubic Bezier Curve)
平滑三次贝塞尔曲线,第一个控制点自动计算,第二个控制点为 (x2, y2),终点为 (x, y)。 -
Q x1 y1, x y (Quadratic Bezier Curve)
绘制二次贝塞尔曲线,控制点为 (x1, y1),终点为 (x, y)。 -
T x y (Smooth Quadratic Bezier Curve)
平滑二次贝塞尔曲线,控制点自动计算,终点为 (x, y)。
(3) 圆弧相关
- A rx ry x-axis-rotation large-arc-flag sweep-flag x y (Arc To)
绘制圆弧:- rx / ry:椭圆的 x 和 y 半径
- x-axis-rotation:x 轴旋转角度
- large-arc-flag:大弧标志(1 为大弧,0 为小弧)
- sweep-flag:弧线方向(1 为顺时针,0 为逆时针)
- (x, y):终点坐标
(4) 关闭路径
- Z 或 z (Close Path)
关闭当前路径,连接起点和终点。
3. 示例
示例 1:矩形
<path d="M10 10 H 90 V90 H 10 Z" fill="none" stroke="black" />
说明:
- M10 10:移动到 (10, 10)。
- H90:水平线到 x=90。
- V90:垂直线到 y=90。
- H10:水平线回到 x=10。
- Z:闭合路径。
示例 2:圆弧
<path d="M50 50 A40 40 0 1 1 90 90" fill="none" stroke="black" />
说明:
- M50 50:移动到 (50, 50)。
- A40 40 0 1 1 90 90:绘制一个半径为 40 的椭圆弧,起点 (50, 50),终点 (90, 90),顺时针方向,使用大弧。
4. 优点
- 灵活性高:可以绘制任何形状
- 高效:减少了节点数量和文件体积
- 组合型强:可以结合直线和曲线,创建复杂的几何图形
5. 注意事项
- 命令大小写:大写为绝对坐标,小写为相对坐标
- 路径优化:路径数据可以简化,减少文件大小
- 填充规则:通过 fill-rule 控制路径的填充方式,如 nonzero 和 evenodd
动画和交互性
SVG 动画
如何使用 <animation>
元素创建简单动画
CSS 与 JavaScript 交互
- 如何通过
CSS
为 SVG 元素添加样式 - 使用
JavaScript
控制 SVG 的动态效果
动画示例
让一个圆形在页面加载后移动
<circle cs="50" cy="50" r="40" fill="blue">
<animation attributeName="cx" from="50" to="150" dur="2s" repeatCount="indefinite" />
</circle>
高级 SVG 技巧
- 渐变与图案填充:使用
<linearGradient>
和<pattern>
创建渐变和图案效果 - 滤镜效果:使用
<filter>
为图形添加阴影、模糊等效果 - 文本与 SVG 的结合:如何使用
<text>
元素在 SVG 中嵌入文本,并设置字体样式
总结
通过这篇文章,我们学习了 SVG 的基础知识,并使用原生 SVG 绘制了一个简单的流程图。SVG 的优势在于它是矢量图形,能够在放大时保持清晰,同时提供丰富的交互性。通过掌握 SVG 的基础语法和常用元素,你可以创建更加复杂和灵活的图形,用于展示流程图、图标或其他可视化内容。
下一步,你可以尝试添加更多的图像元素,并通过 CSS 和 JavaScript 与 SVG 进行交互,创建更高级的流程图应用。而在下一篇中,我们将介绍另一种技术方案-Canvas
的基础知识