深入 SVG:矢量图形、滤镜与动态交互开发指南
1.SVG 详细介绍
SVG(Scalable Vector Graphics) 是一种基于 XML 的矢量图形格式,用于描述二维图形。
1. 命名空间 (Namespace) ★ 了解
-
命名空间 URI:
http://www.w3.org/2000/svg
-
用途:在 XML 或 XHTML 中区分不同标记语言的元素。
-
声明方式:
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><!-- SVG 内容 --> </svg>
2. SVG API ★ 了解
-
DOM API:通过 JavaScript 操作 SVG 元素。
-
创建元素:
document.createElementNS(namespaceURI, tagName)
-
createElementNS
是 JavaScript 中用于 创建带有命名空间(Namespace)的 XML/SVG 元素 的方法。它的核心作用是明确指定元素所属的标记语言规范(如 SVG、XHTML 等),确保浏览器能正确解析和渲染元素标记语言 命名空间 URI SVG http://www.w3.org/2000/svg
XHTML http://www.w3.org/1999/xhtml
MathML http://www.w3.org/1998/Math/MathML
-
示例:
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("width", "100"); svg.setAttribute("height", "100"); document.body.appendChild(svg);
-
-
SVG DOM 接口:如
SVGElement
,SVGRectElement
,SVGPathElement
等,提供特定元素的属性和方法,用于在代码中操作不同类型的 SVG 元素。它们属于 SVG DOM(文档对象模型)规范,提供了特定 SVG 元素的属性和方法接口 对应的 SVG 元素 作用 SVGElement
所有 SVG 元素的基础接口 提供所有 SVG 元素共有的属性和方法(如 id
,className
,style
等)SVGRectElement
<rect>
操作矩形元素(如修改 x
,y
,width
,height
等属性)SVGPathElement
<path>
操作路径元素(如动态修改 d
属性) -
动画 API:支持 SMIL(已部分弃用)、CSS 动画或 JavaScript 动画库(如 GSAP)。
(1) SVGElement
- 基础功能 ★ 了解
const svg = document.querySelector('svg');
console.log(svg instanceof SVGElement); // true// 通用方法
svg.setAttribute('width', '200');
svg.addEventListener('click', () => alert('SVG被点击了'));
(2) SVGRectElement
- 操作矩形 ★ 了解
const rect = document.querySelector('rect');
console.log(rect instanceof SVGRectElement); // true// 特有属性
rect.x.baseVal.value = 10; // 修改 x 坐标
rect.width.baseVal.value = 50; // 修改宽度
rect.rx.baseVal.value = 5; // 修改圆角半径
(3) SVGPathElement
- 操作路径 ★ 了解
const path = document.querySelector('path');
console.log(path instanceof SVGPathElement); // true// 动态修改路径
path.setAttribute('d', 'M10 10 L50 50'); // 获取路径总长度(用于动画)
const pathLength = path.getTotalLength();
(4)完整实例 ★ 了解
<!DOCTYPE html>
<html>
<body><svg id="mySvg" width="200" height="200" style="border:1px solid #ddd"></svg><button id="addRect">添加矩形</button><button id="addPath">添加路径</button><script>const svg = document.getElementById('mySvg');// 添加矩形document.getElementById('addRect').addEventListener('click', () => {const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');rect.setAttribute('x', '10');rect.setAttribute('y', '10');rect.setAttribute('width', '50');rect.setAttribute('height', '50');rect.setAttribute('fill', getRandomColor());// 类型断言为 SVGRectElementconst rectElement = rect instanceof SVGRectElement ? rect : null;if (rectElement) {rectElement.addEventListener('click', () => {rectElement.width.baseVal.value *= 1.2; // 点击放大宽度});}svg.appendChild(rect);});// 添加路径document.getElementById('addPath').addEventListener('click', () => {const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');path.setAttribute('d', 'M10 80 Q 50 10 100 80 T 180 80');path.setAttribute('stroke', 'black');path.setAttribute('fill', 'none');// 类型断言为 SVGPathElementconst pathElement = path instanceof SVGPathElement ? path : null;if (pathElement) {console.log('路径长度:', pathElement.getTotalLength());}svg.appendChild(path);});function getRandomColor() {return `hsl(${Math.random() * 360}, 70%, 50%)`;}</script>
</body>
</html>
3. 常用 SVG 代码示例 ★ 基础
示例 3.1 - 基本形状
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 基本形状</title>
</head>
<body><svg width="400" height="300"><!-- 矩形 --><rect x="10" y="10" width="50" height="30" fill="blue" stroke="black" stroke-width="2"/><!-- 圆形 --><circle cx="100" cy="50" r="30" fill="red"/><!-- 椭圆 --><ellipse cx="200" cy="50" rx="40" ry="20" fill="green"/><!-- 线条 --><line x1="10" y1="100" x2="150" y2="100" stroke="purple" stroke-width="3"/><!-- 折线 --><polyline points="10,150 50,120 90,180" fill="none" stroke="orange"/><!-- 多边形 --><polygon points="200,150 250,120 300,180" fill="yellow" stroke="brown"/></svg>
</body>
</html>
效果展示:
示例 3.2 - 路径(Path)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 路径</title>
</head>
<body><svg width="200" height="200"><path d="M10 80 Q 100 10 190 80 T 370 80"fill="none" stroke="black" stroke-width="2"/></svg>
</body>
</html>
效果展示:
示例 3.3 - 文本
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 文本</title>
</head>
<body><svg width="300" height="100"><text x="20" y="30" font-family="Arial" font-size="20" fill="navy">SVG 文本示例 --> 沐土</text></svg>
</body>
</html>
效果展示:
示例 3.4 - 渐变与图案
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 渐变与图案</title>
</head>
<body><svg width="200" height="200"><defs><linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ff0000"/><stop offset="100%" stop-color="#0000ff"/></linearGradient><pattern id="pattern1" width="20" height="20" patternUnits="userSpaceOnUse"><rect width="10" height="10" fill="#00ff00"/></pattern></defs><rect x="10" y="10" width="100" height="100" fill="url(#grad1)"/><circle cx="150" cy="150" r="30" fill="url(#pattern1)"/></svg>
</body>
</html>
效果展示:
示例 3.5 - 滤镜效果
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 滤镜</title>
</head>
<body><svg width="200" height="200"><defs><filter id="blur"><feGaussianBlur in="SourceGraphic" stdDeviation="5"/></filter><filter id="shadow"><feDropShadow dx="5" dy="5" stdDeviation="3" flood-color="rgba(0,0,0,0.5)"/></filter></defs><rect x="20" y="20" width="100" height="100" fill="teal" filter="url(#shadow)"/><circle cx="150" cy="150" r="30" fill="red" filter="url(#blur)"/></svg>
</body>
</html>
效果展示:
示例 3.6 - 动画
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 动画</title><style>.pulse {animation: pulse 1s infinite;}@keyframes pulse {0% { r: 10; }50% { r: 20; }100% { r: 10; }}</style>
</head>
<body><!-- SMIL 动画(部分浏览器已弃用) --><svg width="200" height="200"><circle cx="50" cy="50" r="20" fill="blue"><animate attributeName="cx" from="50" to="150" dur="2s" repeatCount="indefinite"/></circle></svg><!-- CSS 动画 --><svg width="200" height="200"><circle class="pulse" cx="100" cy="100" r="10" fill="green"/></svg>
</body>
</html>
效果展示:
示例 3.7 - 交互性(JavaScript)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 交互</title>
</head>
<body><svg width="200" height="200"><rect id="btn" x="50" y="50" width="100" height="50" fill="gray"/><script>document.getElementById('btn').addEventListener('click', function() {this.setAttribute('fill', '#' + Math.floor(Math.random()*16777215).toString(16));});</script></svg>
</body>
</html>
效果展示:
示例 3.8 - 视口与 viewBox
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 视口</title>
</head>
<body><svg width="200" height="200" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet"><circle cx="50" cy="50" r="40" fill="orange"/></svg>
</body>
</html>
效果展示:
示例 3.9 - 复用元素
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 复用元素</title>
</head>
<body><svg width="300" height="100"><defs><symbol id="icon" viewBox="0 0 24 24"><path d="M12 2L3 9v12h18V9l-9-7z"/></symbol></defs><use href="#icon" x="10" y="10" width="30" height="30" fill="purple"/><use href="#icon" x="100" y="10" width="30" height="30" fill="pink"/></svg>
</body>
</html>
效果展示:
4.SVG 中常见图形元素的属性总结 ★ 重要
1. 矩形 <rect>
属性列表:
属性 | 含义 | 示例值 |
---|---|---|
x | 矩形左上角的 x 坐标 | "10" |
y | 矩形左上角的 y 坐标 | "10" |
width | 矩形的宽度 | "50" |
height | 矩形的高度 | "30" |
rx | 圆角矩形的水平圆角半径(可选) | "5" |
ry | 圆角矩形的垂直圆角半径(可选) | "5" |
fill | 填充颜色 | "blue" , "#00FF00" |
stroke | 边框颜色 | "black" |
stroke-width | 边框宽度 | "2" |
stroke-dasharray | 虚线边框样式(如 "5,3" 表示 5px 实线 + 3px 空白) | "5,3" |
opacity | 透明度(0-1) | "0.5" |
<rect x="10" y="10" width="50" height="30" rx="5" fill="blue" stroke="black" stroke-width="2"/>
2. 圆形 <circle>
属性 | 含义 | 示例值 |
---|---|---|
cx | 圆心的 x 坐标 | "100" |
cy | 圆心的 y 坐标 | "50" |
r | 圆的半径 | "30" |
fill | 填充颜色 | "red" |
stroke | 边框颜色(同 <rect> ) | "black" |
示例:
<circle cx="100" cy="50" r="30" fill="red"/>
3. 椭圆 <ellipse>
属性 | 含义 | 示例值 |
---|---|---|
cx | 椭圆中心的 x 坐标 | "200" |
cy | 椭圆中心的 y 坐标 | "50" |
rx | 水平半径 | "40" |
ry | 垂直半径 | "20" |
fill | 填充颜色 | "green" |
示例:
<ellipse cx="200" cy="50" rx="40" ry="20" fill="green"/>
4. 线条 <line>
属性 | 含义 | 示例值 |
---|---|---|
x1 , y1 | 起点坐标 | "10" , "100" |
x2 , y2 | 终点坐标 | "150" , "100" |
stroke | 线条颜色(必须设置) | "purple" |
stroke-width | 线条宽度 | "3" |
示例:
<line x1="10" y1="100" x2="150" y2="100" stroke="purple" stroke-width="3"/>
5. 折线 <polyline>
属性 | 含义 | 示例值 |
---|---|---|
points | 一系列坐标点(格式:x1,y1 x2,y2... ) | "10,150 50,120 90,180" |
fill | 填充颜色(通常设为 "none" ) | "none" |
stroke | 线条颜色 | "orange" |
示例:
<polyline points="10,150 50,120 90,180" fill="none" stroke="orange"/>
6. 多边形 <polygon>
属性 | 含义 | 示例值 |
---|---|---|
points | 闭合路径的坐标点(同 <polyline> ) | "200,150 250,120 300,180" |
fill | 填充颜色 | "yellow" |
stroke | 边框颜色 | "brown" |
示例:
<polygon points="200,150 250,120 300,180" fill="yellow" stroke="brown"/>
7. 路径 <path>
★ 重要·难点
属性 | 含义 | 示例值 |
---|---|---|
d | 路径指令(见下方说明) | "M10 80 Q 100 10 190 80" |
fill | 填充颜色("none" 表示不填充) | "none" |
stroke | 路径线条颜色 | "black" |
路径指令(d
属性):
SVG 中的 <path>
元素通过 d
属性定义路径形状,d
属性由一系列路径命令(Path Commands)组成。这些命令通过字母(区分大小写)和坐标参数控制绘制行为。以下是所有命令的详细说明:
1. 基本命令分类 ★ 重要·难点
类型 | 命令 | 含义 | 参数格式 |
---|---|---|---|
移动 |
| 移动到新起点 |
|
直线 |
| 画直线到目标点 |
|
水平/垂直线 |
| 水平画线 |
|
| 垂直画线 |
| |
曲线 |
| 二次贝塞尔曲线 |
|
| 平滑二次贝塞尔曲线(自动对称) |
| |
| 三次贝塞尔曲线 |
| |
| 平滑三次贝塞尔曲线(自动对称) |
| |
弧线 |
| 椭圆弧 |
|
闭合路径 |
| 闭合路径(回到起点) | 无参数 |
1. 基本命令分类
2.1 移动命令(Move)
-
M x,y
/m dx,dy
-
将画笔移动到指定坐标(绝对或相对)。
-
示例:
M 10,20
表示移动到(10,20)
。 -
注意:路径必须以
M
或m
开始。
-
2.2 直线命令(Line)
-
L x,y
/l dx,dy
-
从当前点画直线到目标点。
-
示例:
L 50,50
画线到(50,50)
。
-
-
H x
/h dx
-
水平画线到
x
坐标(y
不变)。
-
-
V y
/v dy
-
垂直画线到
y
坐标(x
不变)。
-
2.3 曲线命令(Curve)
二次贝塞尔曲线(Quadratic Bézier)
-
Q x1,y1 x,y
/q dx1,dy1 dx,dy
-
通过控制点
(x1,y1)
画曲线到(x,y)
。 -
示例:
Q 30,80 50,50
-
起点到终点通过
(30,80)
控制弯曲。
-
-
平滑二次贝塞尔(Smooth Quadratic)
-
T x,y
/t dx,dy
-
自动对称前一控制点,简化连续曲线绘制。
-
示例:
M 10,80 Q 30,10 50,80 T 90,80
-
三次贝塞尔曲线(Cubic Bézier)
-
C x1,y1 x2,y2 x,y
/c dx1,dy1 dx2,dy2 dx,dy
-
两个控制点
(x1,y1)
和(x2,y2)
定义曲线形状。 -
示例:
C 20,100 80,0 100,50
-
平滑三次贝塞尔(Smooth Cubic)
-
S x2,y2 x,y
/s dx2,dy2 dx,dy
-
自动对称前一曲线的第二个控制点。
-
2.4 弧线命令(Arc)
-
A rx,ry x-axis-rotation large-arc-flag sweep-flag x,y
-
参数说明:
-
rx
,ry
:椭圆半径。 -
x-axis-rotation
:椭圆旋转角度(度)。 -
large-arc-flag
:0
表示小弧,1
表示大弧。 -
sweep-flag
:0
表示逆时针,1
表示顺时针。 -
x,y
:终点坐标。
-
-
示例:
// 表示从当前点到 (100,100) 画一个半径为 30 的顺时针小弧。 A 30,30 0 0 1 100,100
-
2.5 闭合命令(Close Path)
-
Z
/z
-
从当前点画直线回路径起点,闭合形状。
-
注意:不区分大小写,无参数。
-
3. 相对 vs 绝对坐标
-
大写字母(如
M
,L
):绝对坐标(基于 SVG 坐标系原点)。 -
小写字母(如
m
,l
):相对坐标(基于当前点)。-
示例:
M 10,10 l 20,20 // 实际绘制到 (30,30)
-
4. 综合示例
绘制一个心形
<path d="M 100,30Q 100,0 70,0Q 40,0 40,30Q 40,60 70,80Q 100,100 120,80Q 150,60 150,30Q 150,0 120,0Q 90,0 90,30Z
" fill="red"/>
解析:
-
M 100,30
:起点。 -
多段
Q
命令绘制二次贝塞尔曲线形成心形轮廓。 -
Z
闭合路径。
5. 高级技巧
-
路径优化:使用
T
/S
简化连续曲线。 -
性能:减少冗余命令(如合并相邻直线)。
-
工具:
-
使用 SVG Path Editor 可视化编辑。
-
通过
path.getTotalLength()
获取路径长度(用于动画)。
-
6. 浏览器支持
所有现代浏览器均支持完整的 d
属性命令,包括:
-
Chrome, Firefox, Safari, Edge (Chromium), Opera。
-
注意:旧版 IE 可能对复杂路径(如弧线)支持不完整。
path完整的示例代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>SVG Path 命令大全 - 可直接运行示例</title><style>body {font-family: Arial, sans-serif;max-width: 1000px;margin: 0 auto;padding: 20px;line-height: 1.6;}.demo-container {display: flex;flex-wrap: wrap;gap: 30px;margin-top: 20px;}.demo-box {border: 1px solid #ddd;padding: 15px;border-radius: 5px;background: #f9f9f9;width: 400px;}svg {display: block;margin: 10px auto;background: #f0f0f0;}h2 {color: #2c3e50;border-bottom: 2px solid #eee;padding-bottom: 10px;}code {background: #eee;padding: 2px 5px;border-radius: 3px;font-family: monospace;}</style>
</head>
<body>
<h1>SVG Path 命令完整示例</h1><div class="demo-container"><!-- 1. 直线命令 --><div class="demo-box"><h2>1. 直线命令 (M, L, H, V)</h2><svg width="200" height="150" viewBox="0 0 200 150"><path d="M 20,20 L 100,20 L 100,100 H 20 V 50"fill="none" stroke="red" stroke-width="3"/><text x="10" y="130" font-size="12">M 20,20 L 100,20 L 100,100 H 20 V 50</text></svg><p><strong>说明:</strong></p><ul><li><code>M 20,20</code> - 移动到起点 (20,20)</li><li><code>L 100,20</code> - 画直线到 (100,20)</li><li><code>L 100,100</code> - 画直线到 (100,100)</li><li><code>H 20</code> - 水平画线到 x=20</li><li><code>V 50</code> - 垂直画线到 y=50</li></ul></div><!-- 2. 二次贝塞尔曲线 --><div class="demo-box"><h2>2. 二次贝塞尔曲线 (Q, T)</h2><svg width="200" height="150" viewBox="0 0 200 150"><path d="M 20,50 Q 80,0 140,50 T 260,50"fill="none" stroke="blue" stroke-width="3"/><circle cx="80" cy="0" r="3" fill="green"/><circle cx="200" cy="50" r="3" fill="green"/><text x="10" y="130" font-size="12">M 20,50 Q 80,0 140,50 T 260,50</text></svg><p><strong>说明:</strong></p><ul><li><code>Q 80,0 140,50</code> - 通过控制点 (80,0) 画曲线到 (140,50)</li><li><code>T 260,50</code> - 自动对称控制点继续画曲线</li><li style="color:green">绿点:控制点位置</li></ul></div><!-- 3. 三次贝塞尔曲线 --><div class="demo-box"><h2>3. 三次贝塞尔曲线 (C, S)</h2><svg width="200" height="150" viewBox="0 0 200 150"><path d="M 20,100 C 40,20 100,20 120,100 S 180,180 200,100"fill="none" stroke="purple" stroke-width="3"/><circle cx="40" cy="20" r="3" fill="orange"/><circle cx="100" cy="20" r="3" fill="orange"/><circle cx="160" cy="180" r="3" fill="orange"/><text x="10" y="130" font-size="12">M 20,100 C 40,20 100,20 120,100 S 180,180 200,100</text></svg><p><strong>说明:</strong></p><ul><li><code>C 40,20 100,20 120,100</code> - 两个控制点画曲线</li><li><code>S 180,180 200,100</code> - 自动对称第一个控制点</li><li style="color:orange">橙点:控制点位置</li></ul></div><!-- 4. 弧线命令 --><div class="demo-box"><h2>4. 弧线命令 (A)</h2><svg width="200" height="150" viewBox="0 0 200 150"><path d="M 50,50 A 30,50 0 1 1 150,50"fill="none" stroke="brown" stroke-width="3"/><text x="10" y="130" font-size="12">M 50,50 A 30,50 0 1 1 150,50</text></svg><p><strong>参数说明:</strong></p><ul><li><code>A rx,ry x-axis-rotation large-arc-flag sweep-flag x,y</code></li><li><code>30,50</code> - 椭圆半径 (x半径30, y半径50)</li><li><code>0</code> - 不旋转</li><li><code>1</code> - 大弧 (0为小弧)</li><li><code>1</code> - 顺时针方向 (0为逆时针)</li><li><code>150,50</code> - 终点坐标</li></ul></div><!-- 5. 闭合路径 --><div class="demo-box"><h2>5. 闭合路径 (Z)</h2><svg width="200" height="150" viewBox="0 0 200 150"><path d="M 50,20 L 100,50 L 80,100 L 30,80 Z"fill="lightgreen" stroke="darkgreen" stroke-width="3"/><text x="10" y="130" font-size="12">M 50,20 L 100,50 L 80,100 L 30,80 Z</text></svg><p><strong>说明:</strong></p><ul><li><code>Z</code> - 闭合路径(自动从最后一点画直线回起点)</li><li>注意:大小写不敏感 (<code>z</code> 效果相同)</li></ul></div><!-- 6. 综合示例:心形 --><div class="demo-box"><h2>6. 综合示例:心形</h2><svg width="200" height="150" viewBox="0 0 200 150"><path d="M 100,30Q 100,0 70,0Q 40,0 40,30Q 40,60 70,80Q 100,100 120,80Q 150,60 150,30Q 150,0 120,0Q 90,0 90,30Z" fill="red" stroke="darkred" stroke-width="2"/><text x="10" y="130" font-size="12">M 100,30 Q 100,0 70,0 Q 40,0 40,30 ... Z</text></svg><p><strong>说明:</strong></p><ul><li>使用多个 <code>Q</code> (二次贝塞尔曲线) 命令绘制</li><li><code>Z</code> 闭合路径完成形状</li></ul></div>
</div><h2>使用技巧</h2>
<ul><li><strong>相对命令</strong>:小写字母 (<code>m, l, q</code> 等) 使用相对坐标</li><li><strong>路径优化</strong>:连续相同命令可省略字母,如 <code>L 10,10 20,20</code></li><li><strong>工具推荐</strong>:<ul><li><a href="https://yqnn.github.io/svg-path-editor/" target="_blank">SVG Path 可视化编辑器</a></li><li>Adobe Illustrator 或 Inkscape 导出 SVG 路径</li></ul></li>
</ul>
</body>
</html>
8. 文本 <text>
属性 | 含义 | 示例值 |
---|---|---|
x , y | 文本基线起点坐标 | "20" , "30" |
font-family | 字体 | "Arial" |
font-size | 字体大小 | "20" |
fill | 文本颜色 | "navy" |
text-anchor | 文本对齐(start /middle /end ) | "middle" |
示例:
<text x="20" y="30" font-family="Arial" font-size="20" fill="navy">SVG Text</text>
9.通用属性
所有图形元素均可使用以下属性:
属性 | 含义 |
---|---|
fill | 填充颜色(支持颜色名、HEX、RGB等) |
stroke | 边框颜色 |
stroke-width | 边框宽度 |
opacity | 整体透明度(0-1) |
transform | 变换(如 rotate(45) 、scale(2) ) |
10.属性总结
-
基本图形:
<rect>
,<circle>
,<ellipse>
,<line>
,<polyline>
,<polygon>
。 -
高级路径:
<path>
通过指令实现任意形状。 -
文本:
<text>
支持样式和定位。 -
通用样式:
fill
,stroke
,opacity
等可跨元素复用。
5.使用 SVG 绘制的移动端常见返回按钮 ★ 常用
方案 1:直接使用 <path>
绘制
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 返回按钮</title><style>body {display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;}.back-button {width: 40px;height: 40px;cursor: pointer;}.back-button:hover path {fill: #007AFF; /* 悬停时变色 */}</style>
</head>
<body>
<!-- 返回按钮 SVG -->
<svg class="back-button" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--d属性路径说明:M20 11 = 移动到起点(20,11)H7.83 = 水平画线到x=7.83l5.59-5.59= 相对绘制斜线(箭头头部)L12 4 = 绝对坐标画线到(12,4)l-8 8 8 8 = 绘制箭头尾部1.41-1.41 = 调整箭头头部细节L7.83 13 = 画线到(7.83,13)H20v-2 = 完成箭头形状--><pathd="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"fill="#000000"stroke="none"/>
</svg><!-- 下方是路径的详细文字说明 -->
<script>document.addEventListener('DOMContentLoaded', () => {const pathDescription = `【路径命令解析】1. M20 11 : 移动到起点(20,11)2. H7.83 : 水平向左画线到x=7.833. l5.59-5.59: 相对绘制斜线(左上箭头头部)4. L12 4 : 画线到(12,4)5. l-8 8 : 向左下方画线6. 8 8 : 向右下方画线7. 1.41-1.41: 微调箭头形状8. L7.83 13 : 画线到(7.83,13)9. H20v-2 : 完成右侧线条10. z : 闭合路径`;console.log(pathDescription);});
</script>
</body>
</html>
效果展示:
关键点说明:
-
路径 (
d
属性):-
M20 11
:移动到起点 (20, 11)。 -
H7.83
:水平画线到 x=7.83。 -
l5.59-5.59
:相对绘制斜线(箭头头部)。 -
L12 4
:绝对坐标画线到 (12, 4)。 -
l-8 8 8 8
:绘制箭头尾部两段线。 -
1.41-1.41
:调整箭头头部细节。 -
H20v-2z
:闭合路径。
-
-
交互效果:
-
通过 CSS 悬停 (
:hover
) 改变颜色。 -
cursor: pointer
表示可点击。
-
方案 2:使用 <symbol>
复用(适合多个按钮)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>SVG 复用返回按钮</title><style>body {display: flex;gap: 20px;justify-content: center;align-items: center;height: 100vh;margin: 0;}.back-button {width: 40px;height: 40px;cursor: pointer;}.back-button:hover use {fill: #FF3B30; /* 悬停红色 */}</style>
</head>
<body><!-- 定义符号 --><svg style="display: none;"><symbol id="back-arrow" viewBox="0 0 24 24"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></symbol></svg><!-- 复用按钮 --><svg class="back-button"><use href="#back-arrow" fill="#000000"/></svg><svg class="back-button"><use href="#back-arrow" fill="#007AFF"/></svg>
</body>
</html>
优势:
-
复用性:通过
<symbol>
定义一次,多处通过<use>
引用。 -
灵活样式:每个实例可独立设置颜色/大小。
方案3:其他变体(简洁箭头)
如果需要一个更简单的箭头样式,可以修改 d
属性:
<path d="M15 18l-6-6 6-6" fill="none" stroke="#000" stroke-width="2"/>
效果:←
样式的细线箭头。
6.SVG 和 Canvas 的区别 ★ 了解
SVG 和 Canvas 是两种完全不同的网页图形技术,它们在实现方式、适用场景和性能特点上有显著差异。以下是它们的核心区别:
1. 基础概念
特性 | SVG | Canvas |
---|---|---|
类型 | 矢量图形(基于 XML) | 位图(基于 JavaScript API) |
渲染方式 | 保留模式(Retained Mode) | 立即模式(Immediate Mode) |
DOM 支持 | 是(每个图形是 DOM 元素) | 否(只是一个画布像素区) |
分辨率无关 | 是(无限缩放不失真) | 否(放大后像素化) |
2. 技术细节对比
SVG
工作原理:
通过 XML 描述图形,浏览器解析后生成可操作的 DOM 节点。
<svg width="100" height="100"><circle cx="50" cy="50" r="40" fill="red"/>
</svg>
-
特点:
-
支持 CSS 样式和动画。
-
内置事件处理(如
onclick
)。 -
适合静态或交互复杂的图形(如图标、图表)。
-
Canvas
工作原理:
通过 JavaScript 动态绘制像素,无持久化对象。
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(50, 50, 40, 0, Math.PI * 2);
ctx.fill();
-
特点:
-
高性能,适合频繁重绘(如游戏、动态数据可视化)。
-
需要手动管理状态和重绘。
-
无内置事件系统,需通过数学计算实现交互。
-
3. 性能与适用场景
场景 | SVG | Canvas |
---|---|---|
图形复杂度 | 适合少量复杂图形(如矢量图标) | 适合大量简单图形(如粒子效果) |
动态更新频率 | 低(DOM 操作成本高) | 高(直接操作像素) |
交互需求 | 内置事件支持(如点击、悬停) | 需手动计算交互区域 |
动画 | CSS/SMIL 动画或 JS 控制属性 | 必须通过 JS 逐帧重绘 |
典型应用 | 地图、UI 图标、可缩放图表 | 游戏、实时数据可视化、图像处理 |
4. 代码示例对比
绘制一个可点击的圆形
SVG 实现(自带事件):
<svg width="100" height="100"><circle cx="50" cy="50" r="40" fill="red" onclick="alert('Clicked!')"/>
</svg>
Canvas 实现(需手动检测点击):
<canvas id="canvas" width="100" height="100"></canvas>
<script>const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// 绘制圆ctx.fillStyle = 'red';ctx.beginPath();ctx.arc(50, 50, 40, 0, Math.PI * 2);ctx.fill();// 手动检测点击canvas.addEventListener('click', (e) => {const x = e.offsetX, y = e.offsetY;const distance = Math.sqrt((x - 50) ** 2 + (y - 50) ** 2);if (distance <= 40) alert('Clicked!');});
</script>
5. 选择建议
-
用 SVG 如果:
-
需要矢量缩放(如响应式设计)。
-
图形需要单独交互或动画。
-
图形数量较少(避免 DOM 性能问题)。
-
-
用 Canvas 如果:
-
需要高性能渲染(如 60fps 动画)。
-
处理像素级操作(如滤镜、图像分析)。
-
图形数量极多(如上万元素的可视化)。
-
6. 进阶对比
高级功能 | SVG | Canvas |
---|---|---|
文本渲染 | 完美支持(可选中、样式丰富) | 基础支持(需手动处理换行等) |
图像处理 | 有限(通过 <image> 标签) | 强大(像素操作、WebGL 扩展) |
内存占用 | 较高(DOM 节点开销) | 较低(纯像素缓冲区) |
学习曲线 | 简单(声明式语法) | 较陡(需理解绘图 API) |
7.总结
-
SVG 是声明式的矢量图形,适合交互复杂、需要缩放的场景。
-
Canvas 是命令式的位图绘制,适合高性能、动态渲染的场景。
根据项目需求混合使用两者(例如用 SVG 做 UI,Canvas 渲染背景动画)往往是最佳实践。
7.SVG兼容问题汇总 ★ 重要
1. 浏览器兼容性问题
1.1 旧版浏览器(IE 8 及以下)
-
问题:
-
IE 8 及更早版本完全不支持 SVG。
-
IE 9-11 部分支持,但存在 Bug(如滤镜效果、CSS 动画)。
-
-
解决方案:
-
使用 Polyfill(如 SVG for Everybody)或转换为 PNG 备用。
-
通过
<img>
引入 SVG 时,添加onerror
回退:<img src="image.svg" onerror="this.src='fallback.png'" />
-
1.2 Android 4.3 及以下
-
问题:
-
部分 SVG 特性(如
viewport
、transform
)支持不完整。
-
-
解决方案:
-
避免复杂变换,使用简化 SVG 代码。
-
2. 功能兼容性问题
2.1 SVG 滤镜(<filter>
)
-
问题:
-
部分浏览器(如旧版 Firefox)对
feBlend
、feColorMatrix
等滤镜效果支持不完整。
-
-
解决方案:
-
使用 CSS 滤镜(如
filter: blur(5px)
)作为备用。 -
测试效果并简化滤镜链。
-
2.2 SVG 动画
-
问题:
-
SMIL 动画(如
<animate>
)在 Chrome 45+ 已弃用,但部分浏览器仍支持。 -
CSS 动画对
transform
属性的支持不一致。
-
-
解决方案:
-
改用 CSS 动画或 JavaScript 动画库(如 GSAP、Snap.svg)。
-
检测 SMIL 支持并回退:
if (!document.createElementNS('http://www.w3.org/2000/svg', 'animate').toString().includes('SVGAnimateElement')) {console.log('SMIL 不支持'); }
-
2.3 字体与文本
-
问题:
-
<text>
元素在跨平台渲染时可能出现字体不一致或换行错误。
-
-
解决方案:
-
使用
textPath
或手动换行(<tspan>
)。 -
将文本转换为路径(设计工具中操作)。
-
3. 嵌入方式的兼容性
3.1 <img>
标签引入 SVG
-
问题:
-
无法通过 CSS 修改 SVG 内部样式。
-
部分浏览器禁用 SVG 内联脚本。
-
-
解决方案:
-
改用
<object>
或内联 SVG:<object data="image.svg" type="image/svg+xml"></object>
-
3.2 CSS 背景图
-
问题:
-
旧版 iOS Safari 可能无法正确缩放 SVG 背景。
-
-
解决方案:
-
显式设置
background-size
:.element {background: url('image.svg');background-size: 100% 100%; }
-
4. 交互与脚本问题
4.1 事件绑定
-
问题:
-
动态创建的 SVG 元素在旧版 Android 中可能无法触发事件。
-
-
解决方案:
-
使用事件委托(委托到父级 SVG 或 HTML 元素)。
-
4.2 动态修改 SVG
-
问题:
-
直接修改
d
属性(如<path>
)在 IE 中可能不触发重绘。
-
-
解决方案:
-
强制重绘:
path.setAttribute('d', newValue); path.style.transform = 'scale(1)'; // 触发重绘
-
5. 其他常见问题
5.1 尺寸与视口
-
问题:
-
未设置
viewBox
时,某些浏览器可能无法正确缩放 SVG。
-
-
解决方案:
-
始终显式定义
viewBox
和width
/height
:<svg width="100" height="100" viewBox="0 0 100 100">...</svg>
-
5.2 外链资源
-
问题:
-
外部 SVG 文件中的
<use href="external.svg#icon">
在 Firefox 中可能受限。
-
-
解决方案:
-
使用内联 SVG 或工具链(如 Webpack)将 SVG 打包为数据 URI。
-
6.svg兼容性总结
-
主要问题:旧版浏览器(IE/旧移动端)、滤镜/动画支持、动态交互。
-
检测函数:
// Can I Use 也可以直接看 if (Modernizr.svg) {console.log('SVG 支持'); }
-
通用建议:
-
优先使用内联 SVG 以最大化控制权。
-
复杂场景提供 PNG 回退。
-
测试目标平台的关键功能(如动画、滤镜)。
-
通过预处理工具(如 SVGO 优化代码)和渐进增强策略,可以显著降低 SVG 的兼容性风险。
8.SVG 常用小图标集合 ★ 常用
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>前端常用SVG小图标集合</title><style>body {font-family: 'Arial', sans-serif;max-width: 800px;margin: 0 auto;padding: 20px;background-color: #f5f5f5;}h1 {color: #333;text-align: center;margin-bottom: 30px;}.icon-container {display: grid;grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));gap: 20px;margin-top: 20px;}.icon-box {background: white;border-radius: 8px;padding: 15px;box-shadow: 0 2px 5px rgba(0,0,0,0.1);text-align: center;transition: transform 0.2s;}.icon-box:hover {transform: translateY(-5px);}.icon {width: 50px;height: 50px;margin: 0 auto 10px;display: block;}.icon-name {font-weight: bold;color: #444;margin-bottom: 5px;}.icon-desc {font-size: 12px;color: #666;}</style>
</head>
<body>
<h1>前端常用SVG小图标集合</h1><div class="icon-container"><!-- 1. 搜索图标 --><div class="icon-box"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--搜索图标路径说明:- 圆形代表放大镜的镜面- 直线代表放大镜的手柄--><path d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 1 0-.7.7l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0A4.5 4.5 0 1 1 14 9.5 4.5 4.5 0 0 1 9.5 14z"fill="#4285F4"/></svg><div class="icon-name">搜索图标</div><div class="icon-desc">用于搜索框的放大镜图标</div></div><!-- 2. 菜单图标 --><div class="icon-box"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--菜单图标路径说明:- 三条水平线代表菜单选项--><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"fill="#5F6368"/></svg><div class="icon-name">菜单图标</div><div class="icon-desc">移动端常见的汉堡菜单图标</div></div><!-- 3. 关闭图标 --><div class="icon-box"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--关闭图标路径说明:- 两条对角线组成X形状--><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"fill="#EA4335"/></svg><div class="icon-name">关闭图标</div><div class="icon-desc">用于弹窗、标签等的关闭按钮</div></div><!-- 4. 下载图标 --><div class="icon-box"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--下载图标路径说明:- 箭头向下表示下载方向- 横线代表下载内容--><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"fill="#34A853"/></svg><div class="icon-name">下载图标</div><div class="icon-desc">用于文件下载按钮</div></div><!-- 5. 上传图标 --><div class="icon-box"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--上传图标路径说明:- 箭头向上表示上传方向- 横线代表上传内容--><path d="M9 16h6v-6h4l-7-7-7 7h4v6zm-4 2h14v2H5v-2z"fill="#FBBC05"/></svg><div class="icon-name">上传图标</div><div class="icon-desc">用于文件上传按钮</div></div><!-- 6. 用户图标 --><div class="icon-box"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--用户图标路径说明:- 圆形代表用户头像- 路径代表用户身体--><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z"fill="#4285F4"/></svg><div class="icon-name">用户图标</div><div class="icon-desc">用于用户登录、个人中心等</div></div><!-- 7. 设置图标 --><div class="icon-box"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--设置图标路径说明:- 齿轮形状代表设置--><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"fill="#5F6368"/></svg><div class="icon-name">设置图标</div><div class="icon-desc">用于系统设置、偏好设置等</div></div><!-- 8. 主页图标 --><div class="icon-box"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--主页图标路径说明:- 房屋形状代表主页--><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"fill="#EA4335"/></svg><div class="icon-name">主页图标</div><div class="icon-desc">用于返回首页的导航按钮</div></div><!-- 9. 通知图标 --><div class="icon-box"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--通知图标路径说明:- 铃铛形状代表通知--><path d="M12 22c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2zm6-6v-5c0-3.07-1.63-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.64 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"fill="#FBBC05"/></svg><div class="icon-name">通知图标</div><div class="icon-desc">用于显示系统或应用通知</div></div><!-- 10. 收藏图标 --><div class="icon-box"><svg class="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><!--收藏图标路径说明:- 星形代表收藏--><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"fill="#34A853"/></svg><div class="icon-name">收藏图标</div><div class="icon-desc">用于标记收藏内容</div></div>
</div><div style="margin-top: 30px; padding: 15px; background: white; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1);"><h2>使用说明</h2><ol><li>直接复制整个HTML文件保存即可使用</li><li>每个图标都是独立的SVG元素,可以直接复制到其他项目中使用</li><li>通过修改<code>fill</code>属性可以改变图标颜色</li><li>通过修改<code>width</code>和<code>height</code>可以调整图标大小</li><li>所有图标都使用标准的24x24 viewBox,保持清晰度</li></ol>
</div>
</body>
</html>
9.命名空间拓展 ★ 了解
SVG 需要命名空间(Namespace)主要是为了解决 XML 文档中元素和属性名称冲突的问题,确保 SVG 元素能够被正确识别和处理;
1. 命名空间的核心作用
(1) 避免元素名称冲突
当 XML 文档中混合多种标记语言时(例如 SVG + HTML),命名空间可以区分同名元素。
示例:
<html xmlns="http://www.w3.org/1999/xhtml"><body><!-- SVG 画布 --><svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><circle cx="50" cy="50" r="40" fill="red"/></svg><!-- 假设HTML也有一个<circle>元素 --><div class="circle"></div></body>
</html>
-
如果没有命名空间,浏览器无法区分
<circle>
是 SVG 的圆形还是 HTML 的其他元素。
(2) 明确语法规则
命名空间定义了元素的合法结构和属性,确保浏览器/解析器能正确渲染 SVG。
2. SVG 命名空间的声明方式
(1) 内联 SVG(HTML5 中)
所有 SVG 元素继承自 SVGElement
,提供通用属性和事件支持
<!-- 可以省略命名空间(浏览器会自动推断) -->
<svg width="100" height="100"><circle cx="50" cy="50" r="40" fill="blue"/>
</svg>
(2) 独立 SVG 文件或混合 XML
<!-- 必须声明命名空间 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect x="10" y="10" width="80" height="80"/>
</svg>
(3) 动态创建 SVG 元素
// 必须使用 createElementNS 而非 createElement
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute("width", "100");
svg.setAttribute("height", "100");
document.body.appendChild(svg);
(4)完整实例
<!DOCTYPE html>
<html>
<body><svg id="mySvg" width="200" height="200" style="border:1px solid #ddd"></svg><button id="addRect">添加矩形</button><button id="addPath">添加路径</button><script>const svg = document.getElementById('mySvg');// 添加矩形document.getElementById('addRect').addEventListener('click', () => {const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');rect.setAttribute('x', '10');rect.setAttribute('y', '10');rect.setAttribute('width', '50');rect.setAttribute('height', '50');rect.setAttribute('fill', getRandomColor());// 类型断言为 SVGRectElementconst rectElement = rect instanceof SVGRectElement ? rect : null;if (rectElement) {rectElement.addEventListener('click', () => {rectElement.width.baseVal.value *= 1.2; // 点击放大宽度});}svg.appendChild(rect);});// 添加路径document.getElementById('addPath').addEventListener('click', () => {const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');path.setAttribute('d', 'M10 80 Q 50 10 100 80 T 180 80');path.setAttribute('stroke', 'black');path.setAttribute('fill', 'none');// 类型断言为 SVGPathElementconst pathElement = path instanceof SVGPathElement ? path : null;if (pathElement) {console.log('路径长度:', pathElement.getTotalLength());}svg.appendChild(path);});function getRandomColor() {return `hsl(${Math.random() * 360}, 70%, 50%)`;}</script>
</body>
</html>
3. 为什么 HTML5 中可以省略命名空间?
-
浏览器智能推断:当
<svg>
直接嵌入 HTML5 文档时,浏览器会自动将其关联到 SVG 命名空间。 -
历史兼容性:HTML5 规范对混合内容做了特殊处理,简化了写法。
4. 必须显式使用命名空间的场景
场景 | 原因 |
---|---|
XML 文档(非HTML) | XML 严格依赖命名空间来区分元素类型 |
XHTML | XHTML 是 XML 的一种,必须严格声明 |
动态创建 SVG 元素 | JavaScript 无法自动推断命名空间 |
SVG 滤镜/动画等高级功能 | 部分浏览器要求明确命名空间以支持特性(如 <filter> 、<animate> ) |
5. 命名空间的 URI 含义
-
http://www.w3.org/2000/svg
是一个标识符而非实际网址,用于唯一标识 SVG 规范。 -
即使该 URL 不可访问,浏览器仍能识别它代表 SVG。
6. 常见问题
问题1:忘记命名空间导致 SVG 不显示
// 错误写法(创建的是HTML元素,非SVG元素)
const circle = document.createElement("circle");
// 正确写法
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
问题2:混合命名空间冲突
<!-- 错误示例 -->
<svg xmlns="http://example.com/custom-ns"><!-- 浏览器无法识别此命名空间中的SVG元素 --><circle cx="50" cy="50" r="40" fill="green"/>
</svg>
命名空间总结
场景 | 是否需要命名空间 | 示例 |
---|---|---|
内联 SVG(HTML5) | 可选 | <svg><circle/></svg> |
独立 SVG 文件 | 必须 | <svg xmlns="..."><path/></svg> |
动态创建 SVG | 必须 | createElementNS("...", "svg") |
XML/XHTML 文档 | 必须 | <svg xmlns="...">...</svg> |
命名空间是 XML 体系的基石,确保 SVG 在复杂文档环境中能够被正确解析和渲染。
相关文章:
深入 SVG:矢量图形、滤镜与动态交互开发指南
1.SVG 详细介绍 SVG(Scalable Vector Graphics) 是一种基于 XML 的矢量图形格式,用于描述二维图形。 1. 命名空间 (Namespace) ★ 了解 命名空间 URI:http://www.w3.org/2000/svg 用途:在 XML 或 XHTML 中区分不同标…...
从双指针到单调栈,深挖“接雨水”的算法奥秘
从双指针到单调栈,深挖“接雨水”的算法奥秘 大家好,我是你们熟悉的算法领域大牛Echo_Wish。今天我们聊聊经典题目《接雨水》(Trapping Rain Water),不仅仅是讲解,而是深度对比两种高效解法:双…...
Labview和C#调用KNX API 相关东西
叙述:完全没有听说过KNX这个协议...................我这次项目中也是简单的用了一下没有过多的去研究 C#调用示例工程链接(labview调用示例在 DEBUG文件夹里面) 通过网盘分享的文件:KNX调用示例.zip 链接: https://pan.baidu.com/s/1NQUEYM11HID0M4ksetrTyg?pwd…...
Wireshark网络抓包分析使用详解
序言 之前学计网还有前几天备考华为 ICT 网络赛道时都有了解认识 Wireshark,但一直没怎么专门去用过,也没去系统学习过,就想趁着备考的网络相关知识还没忘光,先来系统学下整理点笔记~ 什么是抓包?抓包就是将网络传输…...
linux命令行工具进阶
文章目录 前言ssh免密登录,免密码登录,公私钥查看与修改IP地址临时修改永久修改 mount临时切换根文件系统永久切换根文件系统loop文件partedinitramfsuboot command line 前言 本文记录了一些不经常用到,但在某个时刻需要用到的一些指令。 免…...
【Linux文件IO】Linux中标准IO的API的描述和基本用法
Linux中标准IO的API的描述和基本用法 一、标准IO相关API1、文件的打开和关闭示例代码: 2、文件的读写示例代码:用标准IO(fread、fwrite)实现文件拷贝(任何文件均可拷贝) 3、文件偏移设置示例代码: 4、fgets fputs fget…...
【netstat和ss】Windows和Linux下的,网络连接排查简单案例
网络连接排查利器:netstat与ss命令详解 初识netstat:Windows下的网络连接查看工具 需要查看本机的网络连接情况时,Windows系统提供了一个非常实用的命令:netstat。和findstr组合形成一个有用的组合命令: netstat -a…...
【WPF】MVVM模式实现数据绑定以及Command事件绑定
1.引用类 using System.ComponentModel2.创建Command自定义类 public class DelegateCommand : ICommand{public bool CanExecute(object parameter){if (CanExecuteFunc null)return true;return this.CanExecuteFunc(parameter);}public event EventHandler CanExecuteChan…...
Flutter快速搭建聊天
之前项目中使用的环信聊天,我们的App使用的Flutter开发的 。 所以,就使用的 em_chat_uikit ,这个是环信开发的Flutter版本的聊天。 一开始,我们也用的环信的聊天,是收费的,但是,后面就发现&…...
网络层之IP协议
在讨论传输层时, 我们都只讨论了发送方和接收方的问题, 而没有讨论中间的网络形态的问题. 也就是数据包如何从主机传送到主机的? 如图, 主机B发送数据到主机C, 发送报文需要进行路径选择, 主机B-> F-> G-> H-> C-> D -> 主机C 这条路径是如何被选择出来的?…...
【设计模式】策略模式(Strategy Pattern)详解
策略模式(Strategy Pattern)详解 一、策略模式的定义 策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一组算法,将每个算法封装起来,并使它们可以相互替换,从而让算法的…...
Elasticsearch:构建 AI 驱动的搜索体验
Elasticsearch 介绍 当你开始使用 Elastic 时,你将使用 Elasticsearch Relevance Engine™(ESRE),它专为 AI 搜索应用程序提供支持。借助 ESRE,你可以利用一整套开发者工具,包括 Elastic 的文本搜索、向量…...
数据文件误删除,OceanBase中如何重建受影响的节点
当不慎误删数据文件且当前没有现成的可替换节点时,在OceanBase中,不必急于采取极端措施,可以考虑运用 server_permanent_offline_time 参数,来重建受影响的节点。 原理: server_permanent_offline_time 是 OceanBase数…...
MySQL面试专题
1.什么是BufferPool? Buffer Pool基本概念 Buffer Pool:缓冲池,简称BP。其作用是用来缓存表数据与索引数据,减少磁盘IO操作,提升效率。 Buffer Pool由缓存数据页(Page) 和 对缓存数据页进行描述的控制块 组成, 控制…...
Redmi Note 11 T pro + 刷入 LinegaOs 22.1 记录 手机已经解锁bl.
Redmi Note 11 T pro 刷入 LinegaOs 22.1 记录 手机已经解锁bl. 获取LIneagaOS源码, 以及https://github.com/xiaomi-mediatek-devs 这个组织提供的代码,非常感谢 环境要求: ubuntu 22.04 需要准备的依赖 sudo apt install git curl vim…...
Python+Requests+Pytest+YAML+Allure接口自动化框架
GitHub源码地址(详细注释):源码 调试项目python自主搭建:附项目源码 一、项目介绍 本项目是基于 PythonRequestsPytestYAMLAllure 搭建的 接口自动化测试框架,用于对 REST API 进行测试。 框架的主要特点包括&#…...
如何解决Redis缓存异常问题(雪崩、击穿、穿透)
引言 Redis作为一种高性能的内存数据库,被广泛应用于缓存系统的构建中。然而,在实际应用过程中,我们常常会遇到三种典型的缓存异常问题:缓存雪崩、缓存击穿和缓存穿透。这些问题如果处理不当,可能会导致系统性能下降&…...
如何使用 Postman 进行接口测试?
使用 Postman 这一工具,可以轻松地进行接口测试。以下是一份简单的使用教程,帮助你快速上手。 Postman 接口测试教程:详细步骤及操作技巧...
记一次线上环境JAR冲突导致程序报错org.springframework.web.util.NestedServletException
一、问题描述 有个文件导入功能,用到了Hutool 的加密解密功能,本地运行完全可以,但是线上报错:“org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFou…...
VLAN实验
一:实验拓扑 二:实验需求 1、PC1和PC3所在接口为access接口,属于VLAN 2 2、PC2/4/5/6处于同一网段 其中PC2可以访问PC4/5/6 PC4可以访问PC5不能访问PC6 PC5不能访问PC6 3、PC1/3和PC2/4/5/6不在一个网段,且可以正常通讯 4、…...
FPGA中串行执行方式之状态机
FPGA中串行执行方式之状态机 在FPGA中,默认情况下,逻辑是并行执行的,因为FPGA的硬件资源是并行的。然而,在某些情况下,你可能需要某一段逻辑以串行方式执行。这可以通过以下几种方法实现:使用状态机(Finite State Machine, FSM)、使用计数器控制、使用流水线(Pipel…...
【常用的中间件】
中间件(Middleware)是位于客户端和服务器之间的软件层,用于处理客户端请求和服务器响应之间的各种任务。中间件可以提供多种功能,如负载均衡、消息队列、缓存、身份验证等。以下是常用的中间件及其作用: 1. 消息队列中…...
spring - 十二种事务失效场景
目录 编辑 一、方法内部调用 1、原理: 2、结论: 3、解决方法: 1. 增加一个service,把一个事务的方法移到新增加的service方法里面,然后进行注入再调用 2. 在自己类中注入自己 3. 通过AopContentent 二、访问权限不是pubilc 三、方法用final修饰 四、没有被spr…...
python脚本处理excel文件
1.对比perl和python 分别尝试用perl和python处理excel文件,发现perl的比较复杂,比如说read excel就有很多方式 Spreadsheet::Read use Spreadsheet::ParseExcel 不同的method,对应的取sheet的cell方式也不一样。更复杂的是处理含有中文内…...
C#基础学习(二)C#数组生存手册:从入门到“血压拉满“的奇妙旅程
作为一只C#萌新,当你试图用数组装下整个世界时,系统可能会温柔地弹出一句**"Index was outside the bounds of the array."**。别慌!这份求生指南将用段子教你玩转数组 一、数组是什么 数组简单来说就是由相同元素组成的一个集合&a…...
MySQL 性能优化方向
MySQL 性能优化是一个系统性的工作,涉及数据库设计、查询优化、索引优化、硬件配置等多个方面。以下是 MySQL 性能优化的主要方向和具体优化方案: 一、数据库设计优化 1. 合理设计表结构 规范化设计:避免数据冗余,确保数据一致性。适度反规范化:在查询频繁的场景下,适当…...
2025年- G26-Lc100-57.插入间隔(max、min)--java版
1.题目描述 题目翻译: 给定一个不重叠的区间阵列 intervals,其中intervals[i] [starti, endi]表示第i一个区间的起始位置和结束位置,并且intervals 按照起始位置starti升序排序。 另外,给定一个新的区间newInterval [start, e…...
Burp Suite HTTPS解密原理
HTTPS HTTPS是在HTTP的基础上增加了SSL/TLS协议,提供了数据的加密、完整性校验和身份认证等安全保障。HTTPS的工作过程可以分为两个阶段:握手阶段和数据传输阶段。 流程如下图所示: 通过上面的图可以看到,在TCP建立连接后会发起…...
【ESP32S3】esp32获取串口数据并通过http上传到前端
通过前面的学习(前面没发过,因为其实就是跑它的demo)了解到串口配置以及开启线程实现功能的工作流程,与此同时还有esp32作为STA节点,将数据通过http发送到服务器。 将这两者联合 其实是可以得到一个:esp32获…...
怎么查看linux是Ubuntu还是centos
要确定你的Linux系统是基于Ubuntu还是CentOS,可以通过几种不同的方法来进行判断。下面是一些常用的方法: 要快速判断 Linux 系统是 Ubuntu 还是 CentOS,可通过以下方法综合验证: 一、查看系统信息文件 1. /etc/os-release 文件…...
Qt进程间通信:QSharedMemory 使用详解
1. 什么是 QSharedMemory? QSharedMemory 是 Qt 中用于进程间共享内存的类。它允许多个进程共享一块内存区域,从而避免数据传输时的 IO 操作,提高通信速度。通过共享内存,多个进程可以直接读写这块内存,而无需经过文件…...
【day1】数据结构刷题 链表
一 反转链表 206. 反转链表 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入:head [1,2] 输出:[2,1]…...
使用redis设置店铺状态
知识点: 将前端传过来的status(0,1)通过redis对象以key,values值的形式存放在redis中。 #设置店铺状态 redisTemplate.opsForValue().set(KEY,status); #获取店铺状态 Integer status (Integer) redisTemplate.o…...
基于python+django的商城网站-电子商城管理系统源码+运行
基于 python 开发的电子商城网站,平台采用 B/S 结构,后端采用主流的 Python 语言进行开发,前端采用主流的 Vue.js 进行开发。该系统是给师弟做的课程作业。同学们可以拿去自用。学习问题可以留言哦。 整个平台包括前台和后台两个部分。 前台…...
深度解读 C 语言运算符:编程运算的核心工具
一、引言 在 C 语言的编程世界中,运算符是构建逻辑与运算的基石,它如同一位指挥家,精准地协调着程序中各种数据的操作与处理。C 语言丰富多样的运算符涵盖了算术、关系、逻辑、位运算、赋值以及其他杂项运算等多个领域,为开发者提…...
docker中间件部署
1.docker安装 # 1.卸载旧版本 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine# 2.需要的安装包 yum install -y yum-utils# 3.设置镜像的仓库 # 3.1.默认是国外的&#x…...
【Python Cookbook】字符串和文本(二)
字符串和文本(二) 6.字符串忽略大小写的搜索替换7.最短匹配模式8.多行匹配模式9.将 Unicode 文本标准化10.在正则式中使用 Unicode 6.字符串忽略大小写的搜索替换 你需要以忽略大小写的方式搜索与替换文本字符串。 为了在文本操作时忽略大小写…...
docker pull时报错:https://registry-1.docker.io/v2/
原文:https://www.cnblogs.com/sdgtxuyong/p/18647915 https://www.cnblogs.com/OneSeting/p/18532166 docker 换源,解决连接不上的问题。 编辑以下文件,不存在则创建: vim /etc/docker/daemon.json {"registry-mirrors&qu…...
DeepSeek助力文案,智能音箱如何改变你的生活?
你好,我是三桥君 你有没有为写智能音箱的宣传文案而抓耳挠腮过?三桥君在这方面可是有些感想,今天就来给你唠唠怎么用DeepSeek写出超赞的智能音箱宣传文案。 首先,你得给DeepSeek喂足“料”。这就好比做饭,你得准备好各…...
【机器学习】什么是随机森林?
什么是随机森林? 随机森林(Random Forest)是一种集成学习方法,它通过组合多个决策树来提高预测的准确性和鲁棒性。可以把随机森林看作是“森林”,而森林中的每棵树就是一个决策树。每棵树独立地做出预测,最…...
Nature Machine Intelligence 嵌入式大语言模型使机器人能够在不可预测的环境中完成复杂的任务
近期英国爱丁堡大学发表Nature Machine Intelligence研究工作,提出了一种名为ELLMER(具身大型语言模型支持机器人)的创新框架,通过整合大型语言模型(如GPT-4)、检索增强生成(RAG)、视…...
[特殊字符] 2025蓝桥杯备赛Day13——P10984 [蓝桥杯 2023 国 Python A] 残缺的数字
🔍 2025蓝桥杯备赛Day13——P10984 [蓝桥杯 2023 国 Python A] 残缺的数字 🚀 题目速览 题目难度:⭐⭐⭐(需掌握位运算与组合数学) 考察重点:二进制状态处理、位运算、乘法原理、枚举 P10984 [蓝桥杯 2…...
【AcWing】算法基础课-数学知识
目录 1、质数 1.1 试除法判定质数 暴力解法 优化解法 1.2 分解质因数(试除法) 暴力解法 优化解法 1.3 筛质数 朴素筛法(nlogn) 埃氏筛法(nloglogn) 线性筛法(n) 2、约数 2.1 试除法求约数 2.2 约数个数 2.3 约数之和 2.4 最大公约数 实现方法一 实现方法二 …...
JVM常见概念之条件移动
问题 当我们有分支频率数据时,有什么有趣的技巧可以做吗?什么是条件移动? 基础知识 如果您需要在来自一个分支的两个结果之间进行选择,那么您可以在 ISA 级别做两件不同的事情。 首先,你可以创建一个分支ÿ…...
k8s存储介绍(二)Secret
Kubernetes(K8s)提供了一种安全的方式来存储和管理敏感信息,如密码、OAuth 令牌和 SSH 密钥,这就是 Secret。使用 Secret 可以避免将敏感数据硬编码到 Pod 规范或容器镜像中,从而提高安全性和可管理性。 1. Secret 的…...
Css布局-常规流笔记
https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Normal_Floworghttps://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Normal_Flow 前言 常规流布局是html元素默认布局,凡是没有设置过css布局的html元素,默认布局方式称为常…...
Linux系统管理与编程08:任务驱动综合应用
兰生幽谷,不为莫服而不芳; 君子行义,不为莫知而止休。 [环境] windows11、centos7.9.2207、zabbix6、MobaXterm、Internet环境 [要求] zabbix6.0安装环境:Lamp(linux httpd mysql8.0 php) [步骤] 3 …...
基于 OCO - 2 氧气 A 带辐射数据与地面台站气压观测数据构建近地面气压监测算法方案
基于 OCO - 2 氧气 A 带辐射数据与地面台站气压观测数据构建近地面气压监测算法方案 一、数据获取与准备 (一)OCO - 2 氧气 A 带辐射数据 数据下载:从 OCO - 2 官方数据发布平台(如 NASA 的相关数据存储库),按照研究所需的时间范围(例如,近 5 年的数据以获取足够的样本…...
Linux centos7 虚拟用户访问脚本
下面是脚本: #!/bin/bash #function:创建 vsftpd 虚拟用户脚本 #author: 20250324 IT小旋风# 判断是否是 root 用户 if [ "$USER" ! "root" ]; thenecho "不是 root 用户,无法进行安装操作"exit 1 fi# 关闭防火墙 system…...
HTTP 协议中请求与响应的详细解析
前言:HTTP(Hypertext Transfer Protocol,超文本传输协议)是用于在互联网上传输超文本的协议 --由一个请求和响应组成,一个完整的 HTTP 请求由请求行(Request Line)、请求头(Headers&…...