资源
正文
VSCode
VSC 下安装 SVG 插件。

在编写 SVG 代码时,可以按下 Ctrl
+ Shift
+ P
调出命令面板,以打开 Preview SVG
页面。

图形
矩形 <rect>
创建一个圆角矩形:
x
:左上角 x 坐标
y
:左上角 y 坐标
rx
:圆角水平半径
ry
:圆角垂直半径
width
:矩形宽度
height
:矩形高度
fill
:填充颜色
stroke
:描边颜色
stroke-width
:描边宽度
opacity
:透明度
1 2 3 4
| <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1"> <rect x="50" y="20" rx="20" ry="20" width="150" height="150" style="fill:red;stroke:black;stroke-width:5;opacity:0.5"/> </svg>
|

圆形 <circle>
x
:圆心 x 坐标
y
:圆心 y 坐标
r
:圆半径
1 2 3
| <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1"> <circle cx="100" cy="100" r="50" fill="blue" stroke="black" stroke-width="2" /> </svg>
|

椭圆 <ellipse>
cx
:椭圆中心点 x 坐标
cy
:椭圆中心点 y 坐标
rx
:水平轴半径
ry
:垂直轴半径
1 2 3
| <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1"> <circle cx="100" cy="100" r="50" fill="blue" stroke="black" stroke-width="2" /> </svg>
|

直线 <line>
两点确定一条直线。
x1
:起点 x 坐标
y1
:起点 y 坐标
x2
:终点 x 坐标
y2
:终点 y 坐标
1 2 3
| <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>
points="x1,y1 x2,y2 x3,y3 ..."
, 表示多边形各个顶点的坐标。
1 2 3 4 5 6
| <svg height="210" width="500"> <polygon points="100,10 40,198 190,78 10,78 160,198" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;" /> <polygon points="300,10 240,198 390,78 210,78 360,198" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:nonzero;" /> </svg>
|

Note
Adobe Illustrator 默认使用 Nonzero(非零绕数规则) 作为填充方式,只有在特定情况下才会设置为 Even-Odd(奇偶规则)。
多段 <polyline>
与 <polygon>
元素不同, <polyline>
绘制的线条是未封闭的,即起点和终点不会自动连接。
1 2 3
| <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <polyline points="0,40 40,40 40,80 80,80 80,120 120,120 120,160" style="fill:white;stroke:red;stroke-width:4" /> </svg>
|

路径 <path>
d="path-data"
定义了路径数据,即路径命令序列。路径数据由一系列的路径命令组成,每个路径命令以字母开头,后面跟随一组数字参数。常用的路径命令包括:
M
(移动到)
L
(直线到)
H
(水平线到)
V
(垂直线到)
C
(三次贝塞尔曲线)
S
(光滑曲线)
Q
(二次贝塞尔曲线)
T
(光滑二次贝塞尔曲线)
A
(圆弧)
Z
(闭合路径)等。
对于路径属性 d="M 100 350 q 150 -300 300 0"
:
-
M 100 350
:
-
q 150 -300 300 0
:
-
q
是 “quadratic Bézier curve”(二次贝塞尔曲线)的命令,定义一段曲线。
-
第一个参数 (150, -300)
是控制点相对于当前点的偏移量(相对坐标)。
-
第二个参数 (300, 0)
是曲线的终点相对于当前点的偏移量。
-
从起点 (100, 350)
开始,曲线在控制点 (250, 50)
的影响下,最终到达终点 (400, 350)
。
-
控制点计算:
-
控制点绝对坐标 = 起点 + 偏移量 = (100 + 150, 350 - 300)
= (250, 50)
-
终点绝对坐标 = 起点 + 偏移量 = (100 + 300, 350 + 0)
= (400, 350)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <path id="lineAB" d="M 100 350 l 150 -300" stroke="red" stroke-width="3" fill="none" /> <path id="lineBC" d="M 250 50 l 150 300" stroke="red" stroke-width="3" fill="none" /> <path d="M 175 200 l 150 0" stroke="green" stroke-width="3" fill="none" /> <path d="M 100 350 q 150 -300 300 0" stroke="blue" stroke-width="5" fill="none" /> <g stroke="black" stroke-width="3" fill="black"> <circle id="pointA" cx="100" cy="350" r="3" /> <circle id="pointB" cx="250" cy="50" r="3" /> <circle id="pointC" cx="400" cy="350" r="3" /> </g> <g font-size="30" font="sans-serif" fill="black" stroke="none" text-anchor="middle"> <text x="100" y="350" dx="-30">A</text> <text x="250" y="50" dy="-10">B</text> <text x="400" y="350" dx="30">C</text> </g> </svg>
|

文本 <text>
x
:锚点 x 坐标
y
:锚点 y 坐标
font-family
:字体
font-size
:大小
text-anchor
:属性定义了文本锚点,即文本相对于指定坐标的对齐方式,常用取值有 “start”(默认,左对齐)、“middle”(居中对齐)和 “end”(右对齐)。
1 2 3 4 5 6 7 8 9
| <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <path id="path1" d="M75,20 a1,1 0 0,0 100,0" /> </defs> <text x="10" y="100" style="fill:red;"> <textPath xlink:href="#path1">I love SVG I love SVG</textPath> </text> </svg>
|

其它
属性
stroke
定义轮廓颜色。
1 2 3 4 5 6 7
| <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <g fill="none"> <path stroke="red" d="M5 20 l215 0" /> <path stroke="blue" d="M5 40 l215 0" /> <path stroke="black" d="M5 60 l215 0" /> </g> </svg>
|

stroke-width
定义轮廓宽度。
1 2 3 4 5 6 7
| <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <g fill="none" stroke="black"> <path stroke-width="2" d="M5 20 l215 0" /> <path stroke-width="4" d="M5 40 l215 0" /> <path stroke-width="6" d="M5 60 l215 0" /> </g> </svg>
|

stroke-linecap
定义路径头部样式。
1 2 3 4 5 6 7
| <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <g fill="none" stroke="black" stroke-width="6"> <path stroke-linecap="butt" d="M5 20 l215 0" /> <path stroke-linecap="round" d="M5 40 l215 0" /> <path stroke-linecap="square" d="M5 60 l215 0" /> </g> </svg>
|

stroke-dasharray
创建虚线。
1 2 3 4 5 6 7
| <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <g fill="none" stroke="black" stroke-width="4"> <path stroke-dasharray="5,5" d="M5 20 l215 0" /> <path stroke-dasharray="10,10" d="M5 40 l215 0" /> <path stroke-dasharray="20,10,5,5,5,10" d="M5 60 l215 0" /> </g> </svg>
|

滤镜
Note
SVG 滤镜通常使用 <filter>
元素定义,并通过 filter
属性将其应用于目标元素。
常见的滤镜效果包括:
- 模糊(Blur):使图像产生模糊效果,通过
<feGaussianBlur>
元素实现。
- 阴影(Shadow):为图像添加阴影效果,通过
<feDropShadow>
元素实现。
- 亮度、对比度调整(Brightness, Contrast):调整图像的亮度和对比度,通过
<feComponentTransfer>
元素实现。
- 颜色矩阵(Color Matrix):通过颜色矩阵操作修改图像的颜色,通过
<feColorMatrix>
元素实现。
- 混合模式(Blend Mode):将两个图像混合在一起,通过
<feBlend>
元素实现。
1 2 3 4 5 6 7 8 9 10 11
| <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"> <filter id="blur_and_shadow_filter"> <feDropShadow dx="5" dy="5" stdDeviation="3" flood-color="black" flood-opacity="0.5" /> <feGaussianBlur stdDeviation="3" /> </filter> <rect x="50" y="50" width="100" height="80" fill="red" filter="url(#blur_and_shadow_filter)" /> </svg>
|

看样子 AI 并不是很支持这个滤镜。
渐变
线性渐变 <linearGradient>
Note
渐变是一种从一种颜色到另一种颜色的平滑过渡。另外,可以把多个颜色的过渡应用到同一个元素上。
SVG 渐变主要有两种类型:
- 线性渐变 -
<linearGradient>
- 放射性渐变 -
<radialGradient>
1 2 3 4 5 6 7 8 9 10
| <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"> <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%"> <stop offset="0%" stop-color="red" /> <stop offset="100%" stop-color="blue" /> </linearGradient> <rect x="50" y="50" width="100" height="80" fill="url(#gradient)" /> </svg>
|

放射性渐变 <radialGradient>
1 2 3 4 5 6 7 8 9 10
| <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <defs> <radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%"> <stop offset="0%" style="stop-color:rgb(255,255,255); stop-opacity:0" /> <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" /> </radialGradient> </defs> <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" /> </svg>
|

CSS+JS
可以使用 CSS 和 JS 控制 SVG 元素。
创建一个进度条:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <svg xmlns="http://www.w3.org/2000/svg" height="700" width="700"> <style> .text { text-anchor: middle; dominant-baseline: middle; } </style> <circle cx="350" cy="350" r="300" fill="none" stroke="grey" stroke-width="40" stroke-linecap="round" />
<circle class="progress" transform="rotate(-90,350,350)" cx="350" cy="350" r="300" fill="none" stroke="red" stroke-width="40" stroke-linecap="round" stroke-dasharray="0,10000" />
<text class="text" x="350" y="350" font-size="200" fill="red">36</text> </svg>
|

AI 还是有点兼容性问题……
这里将 stroke-dasharray="0,10000"
间隙设置得很大,是为了只显示一个点。虚线的数值可以控制进度条的进度。
写个 JS 控制进度条逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| var progressDom = document.querySelector('.progress'); var textDom = document.querySelector('.text');
function rotateCircle(percent) { var circleLength = Math.floor(2 * Math.PI * parseFloat(progressDom.getAttribute("r"))); var value = percent * circleLength / 100;
var red = 255 + parseInt((0 - 255) / 100 * percent); var green = 0 + parseInt((191 - 0) / 100 * percent); var blue = 0 + parseInt((255 - 0) / 100 * percent);
progressDom.setAttribute("stroke-dasharray", value + ",10000"); progressDom.setAttribute("stroke", `rgb(${red},${green},${blue})`);
textDom.innerHTML = percent + '%'; textDom.setAttribute("fill", `rgb(${red},${green},${blue})`); }
let num = 0; setInterval(() => { num++; if (num > 100) { num = 0; } rotateCircle(num); }, 30);
|
完整代码和效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .text { text-anchor: middle; dominant-baseline: middle; }
body { text-align: center; } </style> </head>
<body> <svg xmlns="http://www.w3.org/2000/svg" height="700" width="700"> <circle cx="350" cy="350" r="300" fill="none" stroke="grey" stroke-width="40" stroke-linecap="round" />
<circle class="progress" transform="rotate(-90,350,350)" cx="350" cy="350" r="300" fill="none" stroke="red" stroke-width="40" stroke-linecap="round" stroke-dasharray="0,10000" />
<text class="text" x="350" y="350" font-size="200" fill="red">36</text> </svg>
<script> var progressDom = document.querySelector('.progress'); var textDom = document.querySelector('.text');
function rotateCircle(percent) { var circleLength = Math.floor(2 * Math.PI * parseFloat(progressDom.getAttribute("r"))); var value = percent * circleLength / 100;
var red = 255 + parseInt((0 - 255) / 100 * percent); var green = 0 + parseInt((191 - 0) / 100 * percent); var blue = 0 + parseInt((255 - 0) / 100 * percent);
progressDom.setAttribute("stroke-dasharray", value + ",10000"); progressDom.setAttribute("stroke", `rgb(${red},${green},${blue})`);
textDom.innerHTML = percent + '%'; textDom.setAttribute("fill", `rgb(${red},${green},${blue})`); }
let num = 0; setInterval(() => { num++; if (num > 100) { num = 0; } rotateCircle(num); }, 30); </script> </body>
</html>
|