svg是一种使用XML技术描述二维图形的语言。我们前端开发写的是html5,其实在h5出现之前就可以在html页面中引入.svg文件来使用了,所以到现在我们可以直接将svg内容直接定义在html页面中了。
常见标签
-
text 和 tspan:基本的文字标签,默认占一行显示。注意的是tspan作为子文本只能在text标签内使用,不能单独使用。
-
rect:可以用来绘制矩形,设置具体的width和height来表示矩形的大小。注意矩形用rx和ry来设置圆角样式。
<rect id="myRect" width="20" height="20" x="10" y="15" fill="#ff0000"/>
-
circle 和 ellipse :circle用来绘制圆形,ellipse 用于绘制椭圆形。 用cx,cy来确定圆心,r表示半径来画圆。
<circle id="myCircle" cx="20" cy="200" r="10" stroke="black" stroke-width="2" fill="#ff0000" />
-
polygon:多边形,这里绘制了一个菱形。points=“x1,y1 x2,y2 x3,y3 x4,y4” 每个x,y一组表示四个坐标点,这四个点连接绘制成一个封闭的图形。
<polygon points="10 10,20 20,10 30,0 20" x="120" y="150" fill="#00ff00"/>
-
line 和 polyline:line可用来画一条直线,通过x1和y1,x2和y2两个坐标点之间连接成一条直线。polyline表示折线,使用的时候和 polygon一样,points属性去标记点连线。注意:使用polyline后需要用fill属性去填充背景色保持一致。
<line x1="10" y1="20" x2="110" y2="120"/> <polyline points="110,120 110,160 150,200 200,200" fill="#fff" stroke="#ff0000"/>
-
path:d属性定义路径的形状,M表示起始点 20,200,H 150 表示垂直延展150px,V 100横向延展100px。M H V算是path中最简单的命令。文章最后的整体示例代码还通过两条path路径和css动画实现了流动线条的样式,其余更详细的path命令用法参考这篇文章https://blog.csdn.net/gxyzlxf/article/details/127022249
<path d="M 20 200 H 150 V 100" stroke-width="4" stroke="#0000ff"></path>
-
defs 和 use:defs定义在svg中可以重复使用的元素,但是通过defs定义的元素并不会在svg画布上展现出来,必须通过use的引用才能展现出来。注意:还需要通过id进行绑定才能引用。
<defs> <circle id="myCircle" cx="20" cy="200" r="10" stroke="black" stroke-width="2" fill="#ff0000" /> </defs> <use href="#myCircle" x="0" y="0"/>
-
g:用于将SVG中的其他元素进行分组。这种分组机制允许你对一组元素应用共同的属性或变换(如平移、旋转、缩放或倾斜),而无需对每个单独的元素单独设置。 这里给这一组标签都添加了边框颜色和宽度,并且都位移到了一个新的坐标点
<g stroke="#00ff00" stroke-width="5" transform="translate(140, 80)"> <polygon points="10 10,20 20,10 30,0 20" x="120" y="150" fill="#00ff00"/> <polygon points="100,120 110,110 120,120 110,130" fill="#00ff00"/> <line x1="10" y1="20" x2="110" y2="120"/> <polyline points="110,120 110,160 150,200 200,200" fill="#fff"/> </g>
常用属性
- fill: 定义图形的填充颜色。可以是颜色名称(如"red")、十六进制颜色代码(如"#FF0000")、RGB(A)函数(如"rgb(255, 0, 0)“或"rgba(255, 0, 0, 0.5)”)、HSL(A)函数,或者引用一个渐变(如
url(#gradientID)
)或图案(如url(#patternID)
)。 - stroke: 定义图形的轮廓颜色。与
fill
属性类似,可以使用颜色名称、十六进制颜色代码、RGB(A)函数、HSL(A)函数,或者引用渐变和图案。 - stroke-width: 定义图形轮廓的宽度,以像素或SVG用户单位(如"2"或"2px")为单位。
- stroke-linecap: 定义线段端点的形状。可选项包括"butt"(默认值,平直的边缘)、“round”(圆形端点)和"square"(方形端点,在端点外增加额外的宽度)。
- stroke-linejoin: 定义当两条线段相交时,它们相交处的形状。可选项包括"miter"(默认,尖角)、“round”(圆角)和"bevel"(斜角)。
- opacity: 定义图形的不透明度。值范围从0(完全透明)到1(完全不透明)。
- transform: 允许你对图形进行变换,如旋转、缩放、倾斜或移动。使用矩阵变换(如
matrix(a,b,c,d,e,f)
)、平移(如translate(x,y)
)、缩放(如scale(x,y)
)、旋转(如rotate(angle,cx,cy)
)和倾斜(如skewX(angle)
或skewY(angle)
)等函数。 - width 和 height: 对于
<svg>
元素,这些属性定义SVG画布的宽度和高度。对于内部图形元素(如<rect>
、<circle>
等),它们定义图形的尺寸。 - x 和 y: 对于一些图形元素(如
<rect>
、<circle>
的cx
和cy
),这些属性定义元素在SVG画布上的位置。 - rx 和 ry: 对于
<rect>
元素,这些属性定义圆角矩形的水平和垂直圆角半径。 - d: 对于
<path>
元素,d
属性定义路径的形状。它是一个“移动至”(M)、“线条至”(L)、“曲线至”©等命令的序列,用于绘制复杂的图形。
svg和canvas的对比
- SVG图形通过DOM元素来呈现,可以与其他HTML元素进行交互,我们可以正常的svg中的任意标签绑定事件
- 由于是矢量图形,SVG可以缩放到任意大小而不失真。Canvas是基于像素的,缩放时可能会导致像素失真。
- 由于SVG是基于矢量的,文件大小通常比位图格式小得多。还可以通过优化路径和使用缩写等方式来减小文件大小
- 性能消耗方面svg可能不如canvas,如果SVG中的DOM节点过多,可能会导致渲染速度变慢。Canvas不与HTML元素直接交互,因此性能也会更高。
总结:需要绘制的图像简单、交互性强或者是矢量图(例如图标),建议使用 SVG。需要支持像素级别的操作,或者复杂的动画和交互(例如数据可视化、交互式游戏),建议使用Canvas。流程图一般图形简单,节点数量不多,会有一些简单的交互现在大多数流程图组件库都是使用 SVG 来进行绘制的,例如:ReactFlow,mxGraph、antvX6等。
综上所述,这些差不多就是svg的一些基础的用法了,以下是完整的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SVG动画示例</title>
<style>
@keyframes progress-animate {
from {
stroke-dashoffset: 0px;
}
to {
stroke-dashoffset: 60px;
}
}
.line-style {
fill: none;
stroke-dasharray: 10px;
}
.line-flow {
animation: progress-animate 4s linear infinite;
}
.line-bg {
fill: none;
stroke-opacity: 0.5;
}
</style>
</head>
<body>
<svg width="400" height="400">
<text x="40" y="40" fill="red" style="font-size:18px; writing-mode: tb;">这是第一段路径</text>
<rect id="myRect" width="20" height="20" x="10" y="15" fill="#ff0000"/>
<path d="M 20 20 V 200" stroke-width="5" stroke="#ff0000" class="line-bg"></path>
<path d="M 20 20 V 200" stroke-width="5" stroke="#ff0000" class="line-flow line-style"></path>
<defs>
<circle id="myCircle" cx="20" cy="200" r="10" stroke="black" stroke-width="2" fill="#ff0000" />
</defs>
<use href="#myCircle" x="0" y="0"/>
<path id="path1" d="M 20 200 H 150 V 100" stroke-width="4" stroke="#0000ff" class="line-bg"></path>
<path d="M 20 200 H 150 V 100" stroke-width="4" stroke="#0000ff" class="line-flow line-style"></path>
<use href="#myCircle" x="130" y="0"/>
<g stroke="#00ff00" stroke-width="5" transform="translate(140, 80)">
<polygon points="10 10,20 20,10 30,0 20" x="120" y="150" fill="#00ff00"/>
<polygon points="100,120 110,110 120,120 110,130" fill="#00ff00"/>
<line x1="10" y1="20" x2="110" y2="120"/>
<polyline points="110,120 110,160 150,200 200,200" fill="#fff"/>
</g>
</svg>
</body>
<script>
let myRect = document.getElementById("myRect")
myRect.addEventListener('click',()=> {
alert('这是一个矩形')
})
document.getElementById("myCircle").style.fill='#0000ff';
</script>
</html>