您现在的位置是:网站首页 > <svg>-SVG矢量图形文章详情
<svg>-SVG矢量图形
陈川
【
HTML
】
5340人已围观
6189字
SVG(Scalable Vector Graphics)是一种基于XML的矢量图形格式,可直接嵌入HTML文档中。它通过数学公式描述图形,支持无限缩放而不失真,适合图标、图表和复杂插图的绘制。
SVG的基本语法
SVG使用XML语法定义图形,基本结构如下:
<svg width="200" height="200" viewBox="0 0 200 200">
<!-- 图形元素放在这里 -->
</svg>
关键属性说明:
width
/height
:定义画布尺寸(像素单位)viewBox
:定义坐标系和纵横比(x y width height)
基本图形绘制
矩形元素
<svg width="200" height="100">
<rect x="10" y="10" width="180" height="80"
fill="steelblue" stroke="black" stroke-width="2"/>
</svg>
属性说明:
x
/y
:左上角坐标rx
/ry
:圆角半径(可选)
圆形元素
<svg width="200" height="200">
<circle cx="100" cy="100" r="80"
fill="gold" stroke="maroon" stroke-width="3"/>
</svg>
路径元素
<svg width="300" height="200">
<path d="M10 80 Q 150 10 290 80 T 150 150 Z"
fill="none" stroke="purple" stroke-width="3"/>
</svg>
路径命令说明:
M
:移动到L
:画直线Q
:二次贝塞尔曲线Z
:闭合路径
高级特性
渐变填充
<svg width="200" height="200">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
</linearGradient>
</defs>
<rect x="10" y="10" width="180" height="180" fill="url(#grad1)"/>
</svg>
滤镜效果
<svg width="200" height="200">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="5"/>
</filter>
</defs>
<circle cx="100" cy="100" r="80" fill="green" filter="url(#blur)"/>
</svg>
动画实现
CSS动画
<svg width="200" height="200">
<style>
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { r: 30; fill: red; }
50% { r: 50; fill: blue; }
100% { r: 30; fill: red; }
}
</style>
<circle class="pulse" cx="100" cy="100" r="30"/>
</svg>
SMIL动画
<svg width="200" height="200">
<rect x="10" y="10" width="50" height="50" fill="orange">
<animate attributeName="x" from="10" to="140" dur="3s" repeatCount="indefinite"/>
</rect>
</svg>
交互功能
JavaScript控制
<svg width="200" height="200" id="interactive">
<circle cx="100" cy="100" r="80" fill="lightgray" id="target"/>
</svg>
<script>
document.getElementById('target').addEventListener('click', function() {
this.setAttribute('fill', getRandomColor());
});
function getRandomColor() {
return `hsl(${Math.random() * 360}, 70%, 60%)`;
}
</script>
鼠标悬停效果
<svg width="200" height="200">
<style>
.hoverable:hover {
fill: #ff5722;
stroke-width: 5px;
}
</style>
<rect class="hoverable" x="50" y="50" width="100" height="100"
fill="#4caf50" stroke="#2e7d32" stroke-width="2"/>
</svg>
实际应用案例
数据可视化
<svg width="400" height="300" id="chart">
<!-- X轴 -->
<line x1="50" y1="250" x2="350" y2="250" stroke="black"/>
<!-- Y轴 -->
<line x1="50" y1="250" x2="50" y2="50" stroke="black"/>
<!-- 柱状图 -->
<rect x="70" y="150" width="40" height="100" fill="#4285F4"/>
<rect x="130" y="100" width="40" height="150" fill="#EA4335"/>
<rect x="190" y="180" width="40" height="70" fill="#FBBC05"/>
<rect x="250" y="50" width="40" height="200" fill="#34A853"/>
<!-- 标签 -->
<text x="90" y="270" text-anchor="middle">Q1</text>
<text x="150" y="270" text-anchor="middle">Q2</text>
<text x="210" y="270" text-anchor="middle">Q3</text>
<text x="270" y="270" text-anchor="middle">Q4</text>
</svg>
自定义图标系统
<svg style="display: none;">
<symbol id="user-icon" viewBox="0 0 24 24">
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
</symbol>
</svg>
<!-- 使用图标 -->
<svg width="24" height="24">
<use href="#user-icon" fill="currentColor"/>
</svg>
性能优化技巧
- 减少节点数量:合并路径比多个独立图形性能更好
- 使用symbol和use:重复图形只定义一次
- 合理使用viewBox:保持图形比例的同时控制显示区域
- 避免复杂滤镜:高斯模糊等滤镜消耗较大
<!-- 优化前 -->
<svg>
<rect x="10" y="10" width="20" height="20"/>
<rect x="40" y="10" width="20" height="20"/>
<rect x="70" y="10" width="20" height="20"/>
</svg>
<!-- 优化后 -->
<svg>
<defs>
<rect id="unit" width="20" height="20"/>
</defs>
<use href="#unit" x="10" y="10"/>
<use href="#unit" x="40" y="10"/>
<use href="#unit" x="70" y="10"/>
</svg>
浏览器兼容性处理
虽然现代浏览器都支持SVG,但需要注意:
- IE9+支持基本SVG功能
- 某些滤镜效果需要前缀
- 外部SVG文件引用方式差异
<!-- 兼容性写法 -->
<svg width="100" height="100">
<!-- 备用内容 -->
<circle cx="50" cy="50" r="40" fill="blue"/>
<foreignObject width="100" height="100">
<div xmlns="http://www.w3.org/1999/xhtml" style="color:red">
您的浏览器不支持SVG
</div>
</foreignObject>
</svg>
SVG与Canvas对比
特性 | SVG | Canvas |
---|---|---|
图形类型 | 矢量(DOM元素) | 位图(像素操作) |
事件支持 | 支持每个图形单独绑定 | 仅支持画布整体绑定 |
性能特点 | 适合静态/少量动态图形 | 适合大量动态图形 |
缩放行为 | 无限缩放不失真 | 放大后会出现像素化 |
修改方式 | 通过DOM API | 通过JavaScript重绘 |
响应式设计中的应用
<svg viewBox="0 0 200 100" preserveAspectRatio="xMidYMid meet">
<!-- 图形会自动缩放保持比例 -->
<rect x="10" y="10" width="180" height="80" fill="lightblue"/>
</svg>
关键属性:
preserveAspectRatio
:控制缩放时的对齐方式meet
(默认):保持比例完整显示slice
:填充整个容器,可能裁剪
常见问题解决方案
图形模糊问题
<!-- 错误示例 -->
<svg width="100px" height="100px" viewBox="0 0 100 100">
<rect width="100" height="100" fill="red"/>
</svg>
<!-- 正确示例 -->
<svg width="100" height="100" viewBox="0 0 100 100">
<rect width="100" height="100" fill="red"/>
</svg>
文本换行处理
<svg width="200" height="100">
<foreignObject width="200" height="100">
<div xmlns="http://www.w3.org/1999/xhtml" style="width:100%">
这里是可以自动换行的长文本内容,超过宽度会自动换行显示
</div>
</foreignObject>
</svg>
工具资源推荐
-
设计工具:
- Adobe Illustrator
- Inkscape(免费开源)
- Figma(在线协作工具)
-
优化工具:
- SVGO(Node.js压缩工具)
- SVGOMG(在线优化工具)
-
代码库:
- Snap.svg(动画库)
- D3.js(数据可视化库)
# 使用SVGO压缩SVG文件
npm install -g svgo
svgo input.svg -o output.svg
上一篇: <picture>-响应式图像
下一篇: <canvas>-图形绘制画布