一、SVG 简介:矢量图形的革命
SVG(Scalable Vector Graphics)是W3C制定的基于XML的矢量图形标准,自2001年发布1.0版本以来,已成为现代Web开发的核心技术。与JPEG、PNG等位图不同,SVG通过数学公式描述图形,具有三大核心优势:
- 无限缩放不失真:无论放大到屏幕尺寸的多少倍,边缘始终锐利
- 轻量化文件体积:复杂图表仅需几KB,比位图小80%以上
- 动态交互能力:每个图形元素都是DOM节点,可直接绑定事件
典型应用场景包括:
- 响应式图标系统(如Material Design图标库)
- 实时数据可视化(股票K线图、地理热力图)
- 动态交互式动画(游戏角色、Loading效果)
- 高分辨率打印设计(海报、宣传册)
二、基础语法:构建SVG的DNA
1. 基本结构
html<svg width="400" height="300" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg">
<!-- 图形元素放在这里 -->
</svg>
viewBox
属性定义坐标系范围,实现响应式布局的核心- 默认尺寸为300×150像素,建议显式设置宽高
2. 基础图形元素
矩形()
html<rect x="50" y="30" width="200" height="100"
rx="10" ry="10"
fill="#4CAF50"
stroke="#2E7D32"
stroke-width="3"/>
rx/ry
实现圆角效果- 支持渐变填充和描边
圆形()
html<circle cx="200" cy="150" r="80"
fill="url(#grad1)"
stroke="purple"
stroke-dasharray="5,3"/>
stroke-dasharray
创建虚线效果- 可结合
<defs>
定义渐变
路径()
html<path d="M100,100
Q150,50 200,100
T300,100"
fill="none"
stroke="red"
stroke-width="2"/>
d
属性包含移动(M)、直线(L)、二次贝塞尔曲线(Q)、平滑曲线(T)等命令- 复杂图形建议使用矢量编辑器生成路径数据
三、进阶技巧:释放SVG的潜能
1. 渐变与滤镜
线性渐变
html<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#FF5722"/>
<stop offset="100%" stop-color="#FFC107"/>
</linearGradient>
</defs>
<rect width="300" height="100" fill="url(#grad1)"/>
发光滤镜
html<defs>
<filter id="glow" x="-30%" y="-30%" width="160%" height="160%">
<feGaussianBlur stdDeviation="5" result="blur"/>
<feComposite in="SourceGraphic" in2="blur" operator="over"/>
</filter>
</defs>
<circle cx="100" cy="100" r="50" filter="url(#glow)" fill="gold"/>
2. 动画实现
CSS动画
html<style>
.spin {
transform-origin: center;
animation: spin 2s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>
<rect class="spin" x="50" y="50" width="100" height="100" fill="blue"/>
SMIL动画(原生SVG动画)
html<rect x="50" y="50" width="100" height="100" fill="green">
<animate attributeName="x" from="50" to="200" dur="3s" repeatCount="indefinite"/>
<animateTransform attributeName="transform" type="rotate"
from="0 100 100" to="360 100 100" dur="5s" repeatCount="indefinite"/>
</rect>
3. 交互开发
鼠标悬停效果
html<rect x="50" y="50" width="100" height="100" fill="#2196F3"
onmouseover="this.setAttribute('fill', '#FF5722')"
onmouseout="this.setAttribute('fill', '#2196F3')"/>
JavaScript控制
html<script>
function changeColor() {
const rect = document.getElementById('myRect');
rect.setAttribute('fill', getRandomColor());
}
function getRandomColor() {
return '#' + Math.floor(Math.random()*16777215).toString(16);
}
</script>
<rect id="myRect" x="50" y="50" width="100" height="100" fill="#4CAF50"
onclick="changeColor()"/>
四、实战案例:数据可视化仪表盘
1. 环形进度条
html<svg width="200" height="200" viewBox="0 0 200 200">
<!-- 背景环 -->
<circle cx="100" cy="100" r="80" stroke="#eee" stroke-width="20" fill="none"/>
<!-- 进度环 -->
<circle id="progress" cx="100" cy="100" r="80" stroke="#4CAF50"
stroke-width="20" fill="none"
stroke-dasharray="502.4"
stroke-dashoffset="0"
transform="rotate(-90 100 100)"/>
<!-- 中心文本 -->
<text x="100" y="110" text-anchor="middle" font-size="24" fill="#333">75%</text>
</svg>
<script>
// 更新进度函数
function updateProgress(percent) {
const circumference = 2 * Math.PI * 80;
const offset = circumference - (percent / 100) * circumference;
document.getElementById('progress').style.strokeDashoffset = offset;
document.querySelector('text').textContent = `${percent}%`;
}
// 模拟数据更新
setInterval(() => {
const randomPercent = Math.floor(Math.random() * 100);
updateProgress(randomPercent);
}, 2000);
</script>
2. 动态折线图
html<svg width="600" height="400" viewBox="0 0 600 400">
<!-- 坐标轴 -->
<line x1="50" y1="350" x2="550" y2="350" stroke="#333" stroke-width="2"/>
<line x1="50" y1="50" x2="50" y2="350" stroke="#333" stroke-width="2"/>
<!-- 刻度线 -->
<g stroke="#666" stroke-width="1">
<line x1="100" y1="350" x2="100" y2="355"/>
<line x1="200" y1="350" x2="200" y2="355"/>
<!-- 更多刻度... -->
</g>
<!-- 折线数据 -->
<path id="linePath" d="M100,200 L200,150 L300,250 L400,100 L500,180"
fill="none" stroke="#2196F3" stroke-width="3"/>
<!-- 数据点 -->
<circle cx="100" cy="200" r="6" fill="#FF5722"/>
<circle cx="200" cy="150" r="6" fill="#FF5722"/>
<!-- 更多数据点... -->
<!-- 动态更新效果 -->
<animateTransform xlink:href="#linePath"
attributeName="transform"
type="translate"
from="0,0" to="0,-50"
dur="2s"
begin="click"
fill="freeze"/>
</svg>
五、性能优化与最佳实践
- 复杂图形分组:使用
<g>
标签组织相关元素,减少DOM节点数 - CSS替代属性动画:对简单属性(如颜色、透明度)使用CSS动画而非SMIL
- 外部引用资源:将重复使用的图形定义在
<defs>
中,通过<use>
复用 - 响应式设计技巧:
html<svg viewBox="0 0 800 600" preserveAspectRatio="xMidYMid meet">
<!-- 图形内容 -->
</svg>
- 浏览器兼容性:
- IE9+支持基本SVG功能
- 对于动画,建议提供CSS回退方案
- 使用Autoprefixer处理CSS前缀
六、学习资源推荐
- 官方文档:
- MDN SVG教程
- W3C SVG规范
- 工具推荐:
- 矢量编辑:Inkscape(免费)、Adobe Illustrator
- 动画制作:GSAP、Snap.svg
- 代码生成:SVGOMG(优化工具)、Figma(设计转代码)
- 进阶学习:
- WebGL与SVG结合(Three.js + SVGOverlay)
- SVG与Canvas混合渲染技术
- Web Components封装可复用SVG组件
通过掌握这些核心技术和实战技巧,您将能够创建出既美观又高性能的Web图形解决方案。SVG的强大之处在于它既是设计师的画布,也是开发者的编程接口,这种双重特性使其成为现代Web开发中不可或缺的技术栈组成部分。