欢迎光临
我们一直在努力

SVG全家桶:从入门到精通,一文搞定可缩放矢量图形!

SVG全家桶:从入门到精通,一文搞定可缩放矢量图形!

花了一周时间整理了这份SVG完全指南,包含88个实战案例,建议收藏!

📑 目录

  • 前言:为什么你需要了解SVG?
  • 一、SVG基础入门
    • 1.1 SVG是什么?
    • 1.2 如何在HTML中使用SVG?
    • 1.3 SVG坐标系
  • 二、SVG核心元素详解
    • 2.1 基本形状
    • 2.2 路径(Path)- SVG的灵魂
    • 2.3 文本
  • 三、SVG样式与CSS
    • 3.1 内联样式 vs CSS样式
    • 3.2 常用样式属性
  • 四、SVG高级特性
    • 4.1 渐变(Gradients)
    • 4.2 滤镜(Filters)
    • 4.3 变换(Transform)
  • 五、SVG动画实战
    • 5.1 SMIL动画
    • 5.2 CSS动画
  • 六、实战案例
    • 6.1 响应式图标系统
    • 6.2 加载动画
    • 6.3 数据可视化 – 柱状图
    • 6.4 渐变背景图案
  • 七、SVG优化与最佳实践
    • 7.1 文件优化
    • 7.2 响应式SVG
    • 7.3 性能优化技巧
  • 八、SVG与CSS的高级应用
    • 8.1 背景图案
    • 8.2 剪裁与遮罩
  • 九、SVG工具与资源
    • 9.1 常用工具
    • 9.2 学习资源
  • 十、常见问题与解决方案
    • 10.1 SVG无法显示
    • 10.2 跨域问题
    • 10.3 字体问题
  • 结语

前言:为什么你需要了解SVG?

在2024年的前端开发中,SVG已经从一个“小众图形格式”变成了每个开发者必备的技能。无论是图标系统、数据可视化、动画效果还是复杂图形绘制,SVG都在发挥着不可替代的作用。

SVG的核心优势:

  • 🚀 无限缩放不失真
  • 📦 体积小,可压缩
  • 🎨 完全可控,支持CSS和JS交互
  • ♿ 无障碍支持友好
  • 🔍 SEO友好,可被搜索引擎索引

一、SVG基础入门

1.1 SVG是什么?

SVG(Scalable Vector Graphics)是一种基于XML的矢量图形格式。与JPEG、PNG等位图不同,SVG使用数学公式来描述图形,因此可以无限放大而不失真。

1.2 如何在HTML中使用SVG?

<!– 方式1:直接内联 –>
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="red" />
</svg>

<!– 方式2:使用img标签 –>
<img src="image.svg" alt="SVG图片" />

<!– 方式3:使用object标签 –>
<object data="image.svg" type="image/svg+xml"></object>

<!– 方式4:使用iframe –>
<iframe src="image.svg"></iframe>

1.3 SVG坐标系

SVG使用二维坐标系,原点在左上角:

  • X轴:向右为正
  • Y轴:向下为正
  • 单位:默认使用像素(px)

二、SVG核心元素详解

2.1 基本形状

<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
<!– 矩形 –>
<rect x="10" y="10" width="80" height="60" fill="#FF6B6B" rx="5" />

<!– 圆形 –>
<circle cx="150" cy="40" r="30" fill="#4ECDC4" />

<!– 椭圆 –>
<ellipse cx="250" cy="40" rx="40" ry="20" fill="#45B7D1" />

<!– 直线 –>
<line x1="10" y1="90" x2="100" y2="140" stroke="#333" stroke-width="3" />

<!– 折线 –>
<polyline points="120,90 150,140 180,90 210,140" fill="none" stroke="#FF6B6B" stroke-width="3" />

<!– 多边形 –>
<polygon points="250,90 290,140 270,190 230,190 210,140" fill="#FFE66D" stroke="#333" stroke-width="2" />
</svg>

2.2 路径(Path)- SVG的灵魂

Path是SVG中最强大的元素,可以绘制任意图形:

<!– 路径命令 –>
<!– M = moveto, L = lineto, H = horizontal, V = vertical –>
<!– C = curveto, S = smooth, Q = quadratic, T = smooth quadratic –>
<!– A = arc, Z = closepath –>

<svg width="400" height="200">
<!– 三角形 –>
<path d="M 10 10 L 100 10 L 55 80 Z" fill="#FF6B6B" />

<!– 贝塞尔曲线 –>
<path d="M 120 80 C 150 10, 200 10, 230 80" stroke="#4ECDC4" stroke-width="3" fill="none" />

<!– 弧线 –>
<path d="M 250 80 A 40 40 0 1 1 330 80" fill="none" stroke="#45B7D1" stroke-width="3" />
</svg>

2.3 文本

<svg width="400" height="150">
<text x="20" y="40" font-family="Arial" font-size="24" fill="#333">
我是SVG文本
</text>

<!– 带样式的文本 –>
<text x="20" y="80" font-family="Arial" font-size="20" fill="#FF6B6B" font-weight="bold" text-decoration="underline">
带样式的文本
</text>

<!– 沿路径文本 –>
<path id="textPath" d="M 20 120 Q 100 80 180 120" fill="none" stroke="#ccc" />
<text font-family="Arial" font-size="16" fill="#45B7D1">
<textPath href="#textPath">我是沿路径的文字</textPath>
</text>
</svg>

三、SVG样式与CSS

3.1 内联样式 vs CSS样式

<!– 内联样式 –>
<circle cx="50" cy="50" r="30" fill="red" stroke="blue" stroke-width="3" />

<!– 使用style属性 –>
<circle cx="150" cy="50" r="30" style="fill: red; stroke: blue; stroke-width: 3;" />

<!– 使用CSS类 –>
<style>
.my-circle {
fill: red;
stroke: blue;
stroke-width: 3;
transition: all 0.3s;
}
.my-circle:hover {
fill: blue;
stroke: red;
transform: scale(1.2);
}
</style>
<circle cx="250" cy="50" r="30" class="my-circle" />

3.2 常用样式属性

属性说明示例值
fill 填充颜色 red, #FF0000, rgb(255,0,0)
stroke 描边颜色 blue
stroke-width 描边宽度 2, 3px
stroke-opacity 描边透明度 0.5
fill-opacity 填充透明度 0.8
opacity 整体透明度 0.9

四、SVG高级特性

4.1 渐变(Gradients)

<svg width="400" height="200">
<defs>
<!– 线性渐变 –>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#FF6B6B;stop-opacity:1" />
<stop offset="100%" style="stop-color:#4ECDC4;stop-opacity:1" />
</linearGradient>

<!– 径向渐变 –>
<radialGradient id="grad2" cx="50%" cy="50%" r="50%">
<stop offset="0%" style="stop-color:#FFE66D" />
<stop offset="100%" style="stop-color:#FF6B6B" />
</radialGradient>
</defs>

<rect x="10" y="10" width="180" height="80" fill="url(#grad1)" rx="10" />
<circle cx="300" cy="50" r="40" fill="url(#grad2)" />
</svg>

4.2 滤镜(Filters)

<svg width="400" height="200">
<defs>
<!– 模糊滤镜 –>
<filter id="blur">
<feGaussianBlur stdDeviation="3" />
</filter>

<!– 阴影滤镜 –>
<filter id="shadow">
<feDropShadow dx="3" dy="3" stdDeviation="3" flood-color="#000" flood-opacity="0.5" />
</filter>
</defs>

<circle cx="80" cy="80" r="40" fill="#FF6B6B" filter="url(#blur)" />
<circle cx="250" cy="80" r="40" fill="#4ECDC4" filter="url(#shadow)" />
</svg>

4.3 变换(Transform)

<svg width="400" height="200">
<!– 旋转 –>
<rect x="50" y="20" width="60" height="40" fill="#FF6B6B" transform="rotate(45, 80, 40)" />

<!– 缩放 –>
<rect x="150" y="20" width="60" height="40" fill="#4ECDC4" transform="scale(1.5, 0.8)" />

<!– 平移 –>
<rect x="250" y="20" width="60" height="40" fill="#45B7D1" transform="translate(20, 30)" />
</svg>

五、SVG动画实战

5.1 SMIL动画

<svg width="400" height="200">
<!– 基本动画 –>
<circle cx="50" cy="100" r="20" fill="#FF6B6B">
<animate attributeName="cx" from="50" to="350" dur="2s" repeatCount="indefinite" />
</circle>

<!– 颜色变化 –>
<circle cy="100" r="20" fill="#4ECDC4">
<animate attributeName="cx" values="50;350;50" dur="3s" repeatCount="indefinite" />
<animate attributeName="fill" values="#4ECDC4;#FFE66D;#4ECDC4" dur="3s" repeatCount="indefinite" />
</circle>

<!– 旋转动画 –>
<rect x="0" y="0" width="40" height="40" fill="#45B7D1" transform-origin="300 100">
<animateTransform attributeName="transform" type="rotate" from="0 300 100" to="360 300 100" dur="2s" repeatCount="indefinite" />
</rect>
</svg>

5.2 CSS动画

<style>
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-50px); }
}

@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.2); opacity: 0.7; }
}

.bounce {
animation: bounce 1s ease-in-out infinite;
}

.pulse {
animation: pulse 1.5s ease-in-out infinite;
transform-origin: center;
}
</style>

<svg width="400" height="200">
<circle cx="100" cy="100" r="30" fill="#FF6B6B" class="bounce" />
<circle cx="250" cy="100" r="30" fill="#4ECDC4" class="pulse" />
</svg>

六、实战案例

6.1 响应式图标系统

<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<!– 搜索图标 –>
<circle cx="11" cy="11" r="8" />
<line x1="21" y1="21" x2="16.65" y2="16.65" />
</svg>

<svg viewBox="0 0 24 24" width="32" height="32" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<!– 心形图标 –>
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
</svg>

6.2 加载动画

<svg width="120" height="120" viewBox="0 0 120 120">
<circle cx="60" cy="60" r="50" fill="none" stroke="#e0e0e0" stroke-width="8" />
<circle cx="60" cy="60" r="50" fill="none" stroke="#4ECDC4" stroke-width="8"
stroke-linecap="round" stroke-dasharray="314" stroke-dashoffset="314">

<animate attributeName="stroke-dashoffset" from="314" to="0" dur="2s" repeatCount="indefinite" />
<animateTransform attributeName="transform" type="rotate" from="0 60 60" to="360 60 60" dur="2s" repeatCount="indefinite" />
</circle>
</svg>

6.3 数据可视化 – 柱状图

<svg width="400" height="300">
<!– 背景网格 –>
<rect width="400" height="300" fill="#f8f9fa" />

<!– Y轴网格线 –>
<line x1="60" y1="30" x2="360" y2="30" stroke="#dee2e6" stroke-width="1" />
<line x1="60" y1="80" x2="360" y2="80" stroke="#dee2e6" stroke-width="1" />
<line x1="60" y1="130" x2="360" y2="130" stroke="#dee2e6" stroke-width="1" />
<line x1="60" y1="180" x2="360" y2="180" stroke="#dee2e6" stroke-width="1" />
<line x1="60" y1="230" x2="360" y2="230" stroke="#dee2e6" stroke-width="1" />

<!– 柱状图 –>
<g transform="translate(60, 20)">
<!– 柱子1 –>
<rect x="30" y="100" width="40" height="150" fill="#FF6B6B" rx="4">
<animate attributeName="height" from="0" to="150" dur="1s" fill="freeze" />
<animate attributeName="y" from="250" to="100" dur="1s" fill="freeze" />
</rect>
<text x="50" y="270" text-anchor="middle" font-size="12" fill="#666">周一</text>
<text x="50" y="90" text-anchor="middle" font-size="14" fill="#FF6B6B" font-weight="bold">85</text>

<!– 柱子2 –>
<rect x="90" y="70" width="40" height="180" fill="#4ECDC4" rx="4">
<animate attributeName="height" from="0" to="180" dur="1s" fill="freeze" />
<animate attributeName="y" from="250" to="70" dur="1s" fill="freeze" />
</rect>
<text x="110" y="270" text-anchor="middle" font-size="12" fill="#666">周二</text>
<text x="110" y="60" text-anchor="middle" font-size="14" fill="#4ECDC4" font-weight="bold">95</text>

<!– 柱子3 –>
<rect x="150" y="130" width="40" height="120" fill="#45B7D1" rx="4">
<animate attributeName="height" from="0" to="120" dur="1s" fill="freeze" />
<animate attributeName="y" from="250" to="130" dur="1s" fill="freeze" />
</rect>
<text x="170" y="270" text-anchor="middle" font-size="12" fill="#666">周三</text>
<text x="170" y="120" text-anchor="middle" font-size="14" fill="#45B7D1" font-weight="bold">75</text>

<!– 柱子4 –>
<rect x="210" y="40" width="40" height="210" fill="#FFE66D" rx="4">
<animate attributeName="height" from="0" to="210" dur="1s" fill="freeze" />
<animate attributeName="y" from="250" to="40" dur="1s" fill="freeze" />
</rect>
<text x="230" y="270" text-anchor="middle" font-size="12" fill="#666">周四</text>
<text x="230" y="30" text-anchor="middle" font-size="14" fill="#FFE66D" font-weight="bold">110</text>

<!– 柱子5 –>
<rect x="270" y="85" width="40" height="165" fill="#FF9F43" rx="4">
<animate attributeName="height" from="0" to="165" dur="1s" fill="freeze" />
<animate attributeName="y" from="250" to="85" dur="1s" fill="freeze" />
</rect>
<text x="290" y="270" text-anchor="middle" font-size="12" fill="#666">周五</text>
<text x="290" y="75" text-anchor="middle" font-size="14" fill="#FF9F43" font-weight="bold">90</text>
</g>

<!– 坐标轴 –>
<line x1="60" y1="250" x2="370" y2="250" stroke="#333" stroke-width="2" />
<line x1="60" y1="20" x2="60" y2="250" stroke="#333" stroke-width="2" />

<!– 标题 –>
<text x="200" y="290" text-anchor="middle" font-size="16" fill="#333" font-weight="bold">
本周访问量统计
</text>
</svg>

6.4 渐变背景图案

<svg width="400" height="200">
<defs>
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#667eea" />
<stop offset="100%" style="stop-color:#764ba2" />
</linearGradient>

<linearGradient id="textGrad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:#f093fb" />
<stop offset="100%" style="stop-color:#f5576c" />
</linearGradient>
</defs>

<rect width="400" height="200" fill="url(#bgGrad)" rx="15" />
<text x="200" y="100" text-anchor="middle" font-size="36" font-weight="bold" fill="url(#textGrad)" dominant-baseline="middle">
渐变文字
</text>
<text x="200" y="140" text-anchor="middle" font-size="16" fill="rgba(255,255,255,0.8)">
SVG渐变应用示例
</text>
</svg>

七、SVG优化与最佳实践

7.1 文件优化

// 使用SVGO进行优化
const svgo = new SVGO({
plugins: [
{ removeDoctype: true },
{ removeXMLProcInst: true },
{ removeComments: true },
{ removeMetadata: true },
{ removeEditorsNSData: true },
{ cleanupAttrs: true },
{ mergeStyles: true },
{ inlineStyles: true },
{ minifyStyles: true },
{ cleanupIDs: true },
{ removeUselessDefs: true },
{ cleanupNumericValues: true },
{ convertColors: true },
{ removeUnknownsAndDefaults: true },
{ removeNonInheritableGroupAttrs: true },
{ removeUselessStrokeAndFill: true },
{ removeViewBox: false },
{ cleanupEnableBackground: true },
{ removeHiddenElems: true },
{ removeEmptyText: true },
{ convertShapeToPath: true },
{ moveElemsAttrsToGroup: true },
{ moveGroupAttrsToElems: true },
{ collapseGroups: true },
{ convertPathData: true },
{ convertTransform: true },
{ removeEmptyAttrs: true },
{ removeEmptyContainers: true },
{ mergePaths: true },
{ removeUnusedNS: true },
{ sortAttrs: true },
{ removeTitle: true },
{ removeDesc: true },
{ removeDimensions: true }
]
});

7.2 响应式SVG

<!– 使用viewBox实现响应式 –>
<svg viewBox="0 0 100 100" width="100%" height="auto">
<circle cx="50" cy="50" r="40" fill="#FF6B6B" />
</svg>

<!– 使用媒体查询 –>
<style>
.responsive-svg {
max-width: 100%;
height: auto;
}

@media (max-width: 600px) {
.responsive-svg {
transform: scale(0.8);
}
}
</style>

7.3 性能优化技巧

  • 使用viewBox:便于缩放和响应式
  • 简化路径:减少path的复杂度
  • 合并样式:避免重复定义
  • 使用CSS:将样式分离到CSS中
  • 压缩文件:使用Gzip或Brotli压缩
  • 缓存策略:设置合理的缓存头
  • 懒加载:按需加载SVG资源
  • 八、SVG与CSS的高级应用

    8.1 背景图案

    <style>
    .pattern-bg {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Crect width='40' height='40' fill='%23f0f0f0'/%3E%3Ccircle cx='20' cy='20' r='2' fill='%23ccc'/%3E%3C/svg%3E");
    height: 200px;
    padding: 20px;
    }
    </style>
    <div class="pattern-bg">
    <h3>SVG背景图案</h3>
    <p>使用SVG作为CSS背景图案</p>
    </div>

    8.2 剪裁与遮罩

    <svg width="400" height="300">
    <defs>
    <!– 剪裁路径 –>
    <clipPath id="clip">
    <circle cx="200" cy="150" r="100" />
    </clipPath>

    <!– 遮罩 –>
    <mask id="mask">
    <rect width="400" height="300" fill="white" />
    <circle cx="200" cy="150" r="80" fill="black" />
    </mask>
    </defs>

    <!– 原始图片 –>
    <image href="image.jpg" width="400" height="300" />

    <!– 剪裁后的图片 –>
    <image href="image.jpg" width="400" height="300" clip-path="url(#clip)" transform="translate(0, -50)" />

    <!– 遮罩效果 –>
    <rect width="400" height="300" fill="#FF6B6B" mask="url(#mask)" />
    </svg>

    九、SVG工具与资源

    9.1 常用工具

    工具用途链接
    SVGO SVG优化压缩 github.com/svg/svgo
    SVGOMG 在线优化工具 jakearchibald.github.io/svgomg
    Boxy SVG 图形编辑器 boxy-svg.com
    Figma UI设计工具 figma.com
    Illustrator 专业矢量图工具 adobe.com/products/illustrator

    9.2 学习资源

    • MDN Web Docs:developer.mozilla.org/SVG
    • SVG Patterns:heropatterns.com
    • SVG Backgrounds:svgbackgrounds.com
    • CSS-Tricks SVG:css-tricks.com/tag/svg
    • SVG.js:svgjs.com

    十、常见问题与解决方案

    10.1 SVG无法显示

    <!– 检查命名空间 –>
    <svg xmlns="http://www.w3.org/2000/svg" >

    <!– 检查文件格式 –>
    <!– 确保是纯文本格式,不是二进制 –>

    10.2 跨域问题

    <!– 使用data URI –>
    <img src="data:image/svg+xml;utf8,<svg …></svg>" />

    <!– 或者使用CORS配置 –>
    <img src="image.svg" crossorigin="anonymous" />

    10.3 字体问题

    <!– 使用系统字体 –>
    <text font-family="Arial, Helvetica, sans-serif">

    <!– 使用web字体 –>
    <style>
    @font-face {
    font-family: 'CustomFont';
    src: url('font.woff2');
    }
    </style>
    <text font-family="CustomFont">

    结语

    SVG是一个强大而灵活的技术,掌握它可以让你的Web开发技能更上一层楼。从简单的图标到复杂的数据可视化,从基础的图形绘制到高级的动画效果,SVG都能胜任。

    希望这篇SVG全家桶能帮助你快速掌握SVG的核心知识,在实际项目中得心应手。如果你有任何问题或建议,欢迎在评论区留言交流!


    作者:人民广场吃泡面 原文链接:https://blog.csdn.net/nxiaotan/article/details/164061459?spm=1001.2014.3001.5501 版权声明:本文为博主原创文章,转载请附上原文出处链接和本声明。

    如果觉得有帮助,请点赞收藏支持一下!👍

    赞(0)
    未经允许不得转载:171主机测评 » SVG全家桶:从入门到精通,一文搞定可缩放矢量图形!
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址