HTML SVG

在本章节中,我们将学习HTML SVG(可缩放矢量图形)的基本概念、语法和用法。SVG是一种用于描述二维矢量图形的XML标记语言,它允许我们在网页中创建高质量、可缩放的图形。

1. 什么是SVG?

SVG(Scalable Vector Graphics,可缩放矢量图形)是一种基于XML的矢量图形格式,用于描述二维图形和图形应用程序。与位图图像(如JPEG、PNG)不同,SVG图形是由数学公式定义的,可以无限缩放而不会失去清晰度。

1.1 SVG的特点

  • 可缩放性:可以无限缩放而不会失真
  • 矢量格式:基于数学公式,文件体积小
  • 可编辑性:可以用文本编辑器修改
  • 可搜索性:内容可以被搜索引擎索引
  • 可脚本化:可以通过JavaScript动态修改
  • 可交互性:支持事件处理和动画
  • 支持滤镜和效果:可以应用各种滤镜和视觉效果

1.2 SVG的应用场景

  • 图标和标志
  • 图表和数据可视化
  • 地图和地理信息
  • 插图和图形设计
  • 动画和交互效果
  • 响应式图形

2. 在HTML中使用SVG

2.1 直接嵌入SVG

可以直接在HTML文档中嵌入SVG代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>直接嵌入SVG</title>
</head>
<body>
    <h1>直接嵌入SVG示例</h1>
    <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
        <circle cx="100" cy="100" r="80" fill="red" />
        <text x="100" y="110" text-anchor="middle" fill="white" font-size="24">Hello SVG</text>
    </svg>
</body>
</html>

2.2 外部引入SVG

可以将SVG保存为单独的.svg文件,然后通过&lt;img&gt;标签、&lt;object&gt;标签或CSS背景图像引入:

<!-- 使用img标签引入 -->
<img src="image.svg" alt="SVG图像">

<!-- 使用object标签引入 -->
<object data="image.svg" type="image/svg+xml" width="200" height="200">
    您的浏览器不支持SVG
</object>

<!-- 使用embed标签引入 -->
<embed src="image.svg" type="image/svg+xml" width="200" height="200">

2.3 SVG的命名空间

SVG元素需要在正确的命名空间中,默认命名空间是http://www.w3.org/2000/svg。在HTML5中,可以省略命名空间声明。

<!-- HTML5中可以省略命名空间 -->
<svg width="200" height="200">
    <!-- SVG内容 -->
</svg>

<!-- XHTML中需要完整的命名空间 -->
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
    <!-- SVG内容 -->
</svg>

3. SVG的基本形状

SVG提供了多种基本形状元素,可以用来创建简单的图形:

3.1 矩形(rect)

<svg width="300" height="200">
    <!-- 基本矩形 -->
    <rect x="10" y="10" width="200" height="150" fill="blue" />
    
    <!-- 带圆角的矩形 -->
    <rect x="220" y="10" width="70" height="150" rx="10" ry="10" fill="red" />
    
    <!-- 带边框的矩形 -->
    <rect x="10" y="170" width="280" height="20" fill="none" stroke="black" stroke-width="2" />
</svg>

属性说明

  • x, y:矩形左上角的坐标
  • width, height:矩形的宽度和高度
  • rx, ry:矩形圆角的半径
  • fill:填充颜色
  • stroke:边框颜色
  • stroke-width:边框宽度

3.2 圆形(circle)

<svg width="300" height="200">
    <!-- 基本圆形 -->
    <circle cx="100" cy="100" r="50" fill="green" />
    
    <!-- 带边框的圆形 -->
    <circle cx="200" cy="100" r="50" fill="none" stroke="purple" stroke-width="5" />
</svg>

属性说明

  • cx, cy:圆心坐标
  • r:半径
  • fill:填充颜色
  • stroke:边框颜色
  • stroke-width:边框宽度

3.3 椭圆(ellipse)

<svg width="300" height="200">
    <!-- 基本椭圆 -->
    <ellipse cx="150" cy="100" rx="100" ry="50" fill="orange" />
    
    <!-- 带边框的椭圆 -->
    <ellipse cx="150" cy="100" rx="80" ry="40" fill="none" stroke="black" stroke-width="3" />
</svg>

属性说明

  • cx, cy:椭圆中心坐标
  • rx:水平半径
  • ry:垂直半径
  • fill:填充颜色
  • stroke:边框颜色
  • stroke-width:边框宽度

3.4 直线(line)

<svg width="300" height="200">
    <!-- 基本直线 -->
    <line x1="10" y1="50" x2="290" y2="50" stroke="red" stroke-width="2" />
    
    <!-- 斜线 -->
    <line x1="10" y1="100" x2="290" y2="150" stroke="blue" stroke-width="3" />
    
    <!-- 垂直线 -->
    <line x1="150" y1="10" x2="150" y2="190" stroke="green" stroke-width="2" />
</svg>

属性说明

  • x1, y1:起点坐标
  • x2, y2:终点坐标
  • stroke:线条颜色
  • stroke-width:线条宽度

3.5 折线(polyline)

<svg width="300" height="200">
    <!-- 基本折线 -->
    <polyline points="50,50 100,100 150,50 200,100 250,50" fill="none" stroke="purple" stroke-width="3" />
    
    <!-- 带填充的折线 -->
    <polyline points="50,150 100,100 150,150 200,100 250,150" fill="yellow" stroke="black" stroke-width="2" />
</svg>

属性说明

  • points:折线的顶点坐标,格式为x1,y1 x2,y2 x3,y3...
  • fill:填充颜色
  • stroke:线条颜色
  • stroke-width:线条宽度

3.6 多边形(polygon)

<svg width="300" height="200">
    <!-- 三角形 -->
    <polygon points="150,50 100,150 200,150" fill="pink" stroke="black" stroke-width="2" />
    
    <!-- 五角星 -->
    <polygon points="150,20 161,85 218,85 174,120 185,185 150,150 115,185 126,120 82,85 139,85" fill="gold" stroke="black" stroke-width="2" />
</svg>

属性说明

  • points:多边形的顶点坐标,格式为x1,y1 x2,y2 x3,y3...
  • fill:填充颜色
  • stroke:线条颜色
  • stroke-width:线条宽度

3.7 路径(path)

路径是SVG中最强大和最复杂的形状元素,可以创建任意复杂的图形:

<svg width="300" height="200">
    <!-- 基本路径 -->
    <path d="M10,50 Q150,10 290,50 T290,150" fill="none" stroke="red" stroke-width="3" />
    
    <!-- 复杂路径 -->
    <path d="M50,100 C50,50 150,50 150,100 C150,150 250,150 250,100" fill="lightblue" stroke="blue" stroke-width="2" />
</svg>

路径命令说明

  • M:移动到(Move To)
  • L:画线到(Line To)
  • H:水平线到(Horizontal Line To)
  • V:垂直线到(Vertical Line To)
  • C:三次贝塞尔曲线(Cubic Bezier Curve)
  • Q:二次贝塞尔曲线(Quadratic Bezier Curve)
  • T:平滑二次贝塞尔曲线(Smooth Quadratic Bezier Curve)
  • S:平滑三次贝塞尔曲线(Smooth Cubic Bezier Curve)
  • A:椭圆弧(Elliptical Arc)
  • Z:闭合路径(Close Path)

4. SVG的文本元素

4.1 基本文本(text)

<svg width="300" height="200">
    <!-- 基本文本 -->
    <text x="10" y="50" fill="black" font-size="20">这是基本文本</text>
    
    <!-- 带样式的文本 -->
    <text x="10" y="80" fill="red" font-size="16" font-weight="bold">粗体红色文本</text>
    
    <!-- 居中对齐的文本 -->
    <text x="150" y="120" text-anchor="middle" fill="blue" font-size="24">居中对齐</text>
    
    <!-- 旋转文本 -->
    <text x="150" y="160" text-anchor="middle" fill="green" font-size="18" transform="rotate(-15, 150, 160)">旋转文本</text>
</svg>

属性说明

  • x, y:文本位置
  • fill:文本颜色
  • font-size:字体大小
  • font-weight:字体粗细
  • text-anchor:文本对齐方式(start, middle, end)
  • transform:变换效果

4.2 多行文本(tspan)

<svg width="300" height="200">
    <text x="10" y="30" font-size="18">
        第一行文本
        <tspan x="10" y="60" fill="red">第二行红色文本</tspan>
        <tspan x="10" y="90" fill="blue" font-weight="bold">第三行蓝色粗体文本</tspan>
    </text>
</svg>

属性说明

  • tspan用于在文本内创建新的行或样式
  • x, y:相对于父文本元素的位置
  • 可以继承或覆盖父文本元素的样式

5. SVG的样式和变换

5.1 内联样式

可以直接在SVG元素上设置样式属性:

<svg width="300" height="200">
    <rect x="10" y="10" width="280" height="180" 
          fill="lightgray" 
          stroke="black" 
          stroke-width="2" 
          rx="5" 
          ry="5" />
</svg>

5.2 CSS样式

可以使用CSS为SVG元素设置样式:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>SVG CSS样式</title>
    <style>
        .my-circle {
            fill: red;
            stroke: black;
            stroke-width: 3;
        }
        
        .my-circle:hover {
            fill: blue;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <svg width="300" height="200">
        <circle cx="150" cy="100" r="80" class="my-circle" />
    </svg>
</body>
</html>

5.3 变换(transform)

SVG支持多种变换效果:

<svg width="400" height="300">
    <!-- 原始图形 -->
    <rect x="50" y="50" width="50" height="50" fill="red" />
    
    <!-- 平移变换 -->
    <rect x="50" y="50" width="50" height="50" fill="blue" transform="translate(100, 0)" />
    
    <!-- 旋转变换 -->
    <rect x="50" y="50" width="50" height="50" fill="green" transform="translate(200, 0) rotate(45)" />
    
    <!-- 缩放变换 -->
    <rect x="50" y="50" width="50" height="50" fill="yellow" transform="translate(0, 100) scale(1.5)" />
    
    <!-- 倾斜变换 -->
    <rect x="50" y="50" width="50" height="50" fill="purple" transform="translate(150, 100) skewX(20)" />
    
    <!-- 组合变换 -->
    <rect x="50" y="50" width="50" height="50" fill="orange" transform="translate(300, 100) rotate(30) scale(1.2)" />
</svg>

变换类型

  • translate(x, y):平移
  • rotate(angle, cx, cy):旋转
  • scale(sx, sy):缩放
  • skewX(angle):水平倾斜
  • skewY(angle):垂直倾斜
  • matrix(a, b, c, d, e, f):矩阵变换

6. SVG的渐变和图案

6.1 线性渐变(linearGradient)

<svg width="300" height="200">
    <!-- 定义线性渐变 -->
    <defs>
        <linearGradient id="myLinearGradient" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" stop-color="red" />
            <stop offset="50%" stop-color="yellow" />
            <stop offset="100%" stop-color="green" />
        </linearGradient>
    </defs>
    
    <!-- 使用线性渐变 -->
    <rect x="10" y="10" width="280" height="180" fill="url(#myLinearGradient)" />
</svg>

属性说明

  • x1, y1, x2, y2:渐变的起点和终点坐标
  • stop:渐变的颜色停止点
  • offset:停止点的位置(0%-100%)
  • stop-color:停止点的颜色

6.2 径向渐变(radialGradient)

<svg width="300" height="200">
    <!-- 定义径向渐变 -->
    <defs>
        <radialGradient id="myRadialGradient" cx="50%" cy="50%" r="50%">
            <stop offset="0%" stop-color="white" />
            <stop offset="100%" stop-color="blue" />
        </radialGradient>
    </defs>
    
    <!-- 使用径向渐变 -->
    <circle cx="150" cy="100" r="80" fill="url(#myRadialGradient)" />
</svg>

属性说明

  • cx, cy:渐变中心坐标
  • r:渐变半径
  • stop:渐变的颜色停止点
  • offset:停止点的位置(0%-100%)
  • stop-color:停止点的颜色

6.3 图案填充(pattern)

<svg width="300" height="200">
    <!-- 定义图案 -->
    <defs>
        <pattern id="myPattern" width="20" height="20" patternUnits="userSpaceOnUse">
            <circle cx="10" cy="10" r="5" fill="black" />
        </pattern>
    </defs>
    
    <!-- 使用图案 -->
    <rect x="10" y="10" width="280" height="180" fill="url(#myPattern)" />
</svg>

属性说明

  • width, height:图案的尺寸
  • patternUnits:图案单位(userSpaceOnUse或objectBoundingBox)

7. SVG的动画

7.1 基本动画(animate)

<svg width="300" height="200">
    <!-- 矩形移动动画 -->
    <rect x="10" y="10" width="50" height="50" fill="red">
        <animate attributeName="x" from="10" to="240" dur="3s" repeatCount="indefinite" />
    </rect>
    
    <!-- 圆形缩放动画 -->
    <circle cx="150" cy="100" r="10" fill="blue">
        <animate attributeName="r" from="10" to="50" dur="2s" repeatCount="indefinite" alternate="true" />
    </circle>
</svg>

属性说明

  • attributeName:要动画的属性
  • from:起始值
  • to:结束值
  • dur:动画持续时间
  • repeatCount:重复次数(indefinite表示无限重复)
  • alternate:是否反向播放

7.2 路径动画(animateMotion)

<svg width="300" height="200">
    <!-- 定义路径 -->
    <defs>
        <path id="motionPath" d="M10,100 Q100,20 200,100 T300,100" fill="none" stroke="gray" />
    </defs>
    
    <!-- 显示路径 -->
    <use href="#motionPath" />
    
    <!-- 沿路径移动的圆形 -->
    <circle cx="10" cy="100" r="10" fill="red">
        <animateMotion dur="5s" repeatCount="indefinite">
            <mpath href="#motionPath" />
        </animateMotion>
    </circle>
</svg>

8. SVG的滤镜效果

8.1 高斯模糊(feGaussianBlur)

<svg width="300" height="200">
    <!-- 定义滤镜 -->
    <defs>
        <filter id="blurFilter">
            <feGaussianBlur in="SourceGraphic" stdDeviation="5" />
        </filter>
    </defs>
    
    <!-- 原始矩形 -->
    <rect x="10" y="50" width="120" height="100" fill="blue" />
    
    <!-- 应用模糊滤镜的矩形 -->
    <rect x="160" y="50" width="120" height="100" fill="blue" filter="url(#blurFilter)" />
</svg>

8.2 阴影效果(feDropShadow)

<svg width="300" height="200">
    <!-- 定义阴影滤镜 -->
    <defs>
        <filter id="shadowFilter">
            <feDropShadow dx="5" dy="5" stdDeviation="3" flood-color="black" flood-opacity="0.5" />
        </filter>
    </defs>
    
    <!-- 应用阴影效果的文本 -->
    <text x="150" y="100" text-anchor="middle" font-size="36" font-weight="bold" fill="red" filter="url(#shadowFilter)">
        阴影文本
    </text>
</svg>

9. SVG的最佳实践

9.1 优化SVG文件

  • 简化路径和形状
  • 移除不必要的元素和属性
  • 使用CSS代替内联样式
  • 合并相似元素
  • 使用压缩工具(如SVGO)优化文件

9.2 响应式设计

  • 使用相对单位(如百分比)
  • 设置viewBox属性
  • 使用preserveAspectRatio控制缩放行为
  • 考虑不同屏幕尺寸

9.3 可访问性

  • 为SVG添加title和desc元素
  • 使用aria属性
  • 确保有适当的颜色对比度
  • 为交互元素添加键盘支持

9.4 性能考虑

  • 避免过度复杂的图形
  • 限制动画数量和复杂度
  • 使用CSS动画代替SMIL动画
  • 考虑使用外部SVG文件进行缓存

10. 常见问题解答

Q: SVG和Canvas有什么区别?

A: SVG是矢量图形,基于XML,适合静态图形和简单动画;Canvas是位图,基于JavaScript,适合复杂动画和游戏。

Q: SVG支持哪些浏览器?

A: 所有现代浏览器都支持SVG,包括Chrome、Firefox、Safari、Edge等。

Q: 如何将SVG转换为其他格式?

A: 可以使用在线工具或图形编辑器(如Inkscape、Illustrator)将SVG转换为PNG、JPEG等格式。

Q: 如何在SVG中添加交互?

A: 可以使用JavaScript为SVG元素添加事件监听器,或者使用CSS伪类(如:hover)。

Q: 如何优化SVG的加载性能?

A: 可以压缩SVG文件、使用外部SVG文件、延迟加载非关键SVG,以及使用适当的缓存策略。

Q: 如何在SVG中使用自定义字体?

A: 可以使用@font-face规则在CSS中定义自定义字体,然后在SVG文本中使用。

11. 练习项目

  1. 创建一个HTML文件,包含以下内容:

    • 页面标题为"HTML SVG练习"
    • 页面头部包含必要的元标签(字符集、视口等)
    • 创建至少5个不同的SVG图形,包括:
      • 矩形、圆形、椭圆
      • 线条、折线、多边形
      • 路径和文本
    • 为SVG图形添加样式,包括:
      • 填充颜色和边框
      • 渐变和图案
      • 变换效果
    • 添加至少2个SVG动画,包括:
      • 基本属性动画
      • 路径动画
    • 创建一个简单的SVG图标,如社交媒体图标或应用图标
    • 使用CSS为SVG元素添加交互效果(如悬停效果)
    • 确保页面在不同设备上都能正常显示
  2. 在浏览器中打开文件,验证SVG图形的显示效果

  3. 测试SVG动画和交互效果

  4. 检查HTML代码是否符合标准

  5. 优化SVG文件,确保良好的性能

12. 小结

  • SVG是一种基于XML的矢量图形格式,用于描述二维图形
  • SVG具有可缩放性、矢量格式、可编辑性等特点
  • 可以直接在HTML中嵌入SVG,也可以外部引入
  • SVG支持多种基本形状,如矩形、圆形、椭圆、线条、折线、多边形和路径
  • 可以使用CSS和JavaScript为SVG添加样式和交互
  • SVG支持渐变、图案、滤镜和动画效果
  • SVG在图标、图表、地图等场景中有广泛应用
  • 最佳实践包括优化SVG文件、响应式设计、可访问性和性能考虑

在下一章节中,我们将学习HTML Canvas,了解如何使用Canvas API在网页中绘制图形和动画。

« 上一篇 HTML iframe 下一篇 » HTML Canvas