Skip to content

8.3 SVG路径和文本

关键词

SVG路径、path元素、文本元素、文本路径、曲线路径、复杂图形、文本排版

学习目标

  • 掌握SVG路径元素的语法和用法
  • 理解路径数据的各种命令
  • 学会在SVG中添加和格式化文本
  • 掌握文本沿路径排列的技术
  • 能够创建复杂的矢量图形

详细内容

8.3.1 SVG路径基础

什么是SVG路径

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

html
<!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>
</head>
<body>
    <h1>SVG路径示例</h1>
    
    <svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
        <!-- 简单直线路径 -->
        <path d="M 10 10 L 100 10" stroke="black" stroke-width="2" fill="none"/>
        
        <!-- 三角形路径 -->
        <path d="M 10 50 L 60 50 L 35 20 Z" fill="blue" stroke="black"/>
        
        <!-- 曲线路径 -->
        <path d="M 10 100 Q 50 50 100 100" stroke="red" stroke-width="3" fill="none"/>
    </svg>
</body>
</html>

路径命令详解

SVG路径使用特定的命令字符:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>路径命令详解</title>
</head>
<body>
    <h1>路径命令示例</h1>
    
    <svg width="500" height="400" xmlns="http://www.w3.org/2000/svg">
        <!-- 移动和直线命令 -->
        <path d="M 50 50 L 150 50 L 150 150 L 50 150 Z" 
              fill="lightblue" stroke="black" stroke-width="2"/>
        <text x="50" y="40" font-family="Arial" font-size="12">M L Z 命令</text>
        
        <!-- 水平和垂直线命令 -->
        <path d="M 200 50 H 300 V 150 H 200 Z" 
              fill="lightgreen" stroke="black" stroke-width="2"/>
        <text x="200" y="40" font-family="Arial" font-size="12">H V 命令</text>
        
        <!-- 曲线命令 -->
        <path d="M 50 200 Q 100 150 150 200" 
              stroke="red" stroke-width="3" fill="none"/>
        <text x="50" y="190" font-family="Arial" font-size="12">Q 二次贝塞尔曲线</text>
        
        <!-- 三次贝塞尔曲线 -->
        <path d="M 200 200 C 220 150 280 150 300 200" 
              stroke="purple" stroke-width="3" fill="none"/>
        <text x="200" y="190" font-family="Arial" font-size="12">C 三次贝塞尔曲线</text>
        
        <!-- 弧形命令 -->
        <path d="M 50 300 A 50 25 0 0 1 150 300" 
              stroke="orange" stroke-width="3" fill="none"/>
        <text x="50" y="290" font-family="Arial" font-size="12">A 弧形</text>
    </svg>
</body>
</html>

8.3.2 复杂路径绘制

创建复杂图形

组合多个路径命令创建复杂形状:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>复杂路径绘制</title>
</head>
<body>
    <h1>复杂SVG图形</h1>
    
    <svg width="600" height="400" xmlns="http://www.w3.org/2000/svg">
        <!-- 星形图案 -->
        <path d="M 100 50 L 110 80 L 140 80 L 118 98 L 128 128 L 100 110 L 72 128 L 82 98 L 60 80 L 90 80 Z" 
              fill="gold" stroke="orange" stroke-width="2"/>
        <text x="70" y="40" font-family="Arial" font-size="14">五角星</text>
        
        <!-- 花朵图案 -->
        <path d="M 250 100 
                 C 220 80 220 60 250 60 
                 C 280 60 280 80 250 100 
                 C 280 120 280 140 250 140 
                 C 220 140 220 120 250 100 
                 C 230 70 270 70 250 100 
                 C 230 130 270 130 250 100" 
              fill="pink" stroke="red" stroke-width="2"/>
        <text x="220" y="50" font-family="Arial" font-size="14">花朵</text>
        
        <!-- 心形图案 -->
        <path d="M 400 80 
                 C 400 60 380 60 380 80 
                 C 380 60 360 60 360 80 
                 C 360 90 380 110 400 130 
                 C 420 110 440 90 440 80 
                 C 440 60 420 60 420 80 
                 C 420 60 400 60 400 80 Z" 
              fill="red" stroke="darkred" stroke-width="2"/>
        <text x="370" y="50" font-family="Arial" font-size="14">心形</text>
        
        <!-- 波浪线 -->
        <path d="M 50 200 Q 100 170 150 200 Q 200 230 250 200 Q 300 170 350 200 Q 400 230 450 200" 
              stroke="blue" stroke-width="4" fill="none"/>
        <text x="50" y="190" font-family="Arial" font-size="14">波浪线</text>
        
        <!-- 螺旋线 -->
        <path d="M 300 300 
                 Q 320 280 340 300 
                 Q 360 320 340 340 
                 Q 320 360 300 340 
                 Q 280 320 300 300 
                 Q 310 290 320 300 
                 Q 330 310 320 320 
                 Q 310 330 300 320 
                 Q 290 310 300 300" 
              stroke="green" stroke-width="3" fill="none"/>
        <text x="270" y="250" font-family="Arial" font-size="14">螺旋线</text>
    </svg>
</body>
</html>

8.3.3 SVG文本元素

基本文本显示

在SVG中添加文本内容:

html
<!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>
</head>
<body>
    <h1>SVG文本示例</h1>
    
    <svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
        <!-- 基本文本 -->
        <text x="50" y="50" font-family="Arial" font-size="16" fill="black">基本文本</text>
        
        <!-- 样式文本 -->
        <text x="50" y="80" font-family="Times New Roman" font-size="18" 
              font-weight="bold" fill="blue">粗体蓝色文本</text>
        
        <!-- 斜体文本 -->
        <text x="50" y="110" font-family="Arial" font-size="16" 
              font-style="italic" fill="red">斜体红色文本</text>
        
        <!-- 装饰文本 -->
        <text x="50" y="140" font-family="Arial" font-size="16" 
              text-decoration="underline" fill="green">下划线文本</text>
        
        <!-- 旋转文本 -->
        <text x="200" y="100" font-family="Arial" font-size="16" 
              transform="rotate(45 200 100)" fill="purple">旋转文本</text>
        
        <!-- 多行文本 -->
        <text x="50" y="200" font-family="Arial" font-size="14" fill="black">
            <tspan x="50" dy="0">第一行文本</tspan>
            <tspan x="50" dy="20">第二行文本</tspan>
            <tspan x="50" dy="20">第三行文本</tspan>
        </text>
    </svg>
</body>
</html>

文本格式化和样式

使用tspan元素实现富文本格式:

html
<!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>
</head>
<body>
    <h1>SVG文本格式化</h1>
    
    <svg width="600" height="400" xmlns="http://www.w3.org/2000/svg">
        <!-- 混合样式文本 -->
        <text x="50" y="50" font-family="Arial" font-size="16">
            这是<tspan font-weight="bold" fill="red">粗体红色</tspan>和
            <tspan font-style="italic" fill="blue">斜体蓝色</tspan>的混合文本
        </text>
        
        <!-- 上标和下标 -->
        <text x="50" y="100" font-family="Arial" font-size="16">
            化学公式:H<tspan baseline-shift="sub" font-size="12">2</tspan>O
            数学公式:x<tspan baseline-shift="super" font-size="12">2</tspan> + y<tspan baseline-shift="super" font-size="12">2</tspan>
        </text>
        
        <!-- 文本路径 -->
        <defs>
            <path id="wave" d="M 50 200 Q 150 150 250 200 Q 350 250 450 200"/>
        </defs>
        <path d="M 50 200 Q 150 150 250 200 Q 350 250 450 200" 
              stroke="gray" stroke-width="1" fill="none"/>
        <text font-family="Arial" font-size="14" fill="black">
            <textPath href="#wave">沿着波浪线排列的文本内容</textPath>
        </text>
        
        <!-- 圆形文本路径 -->
        <defs>
            <path id="circle" d="M 100 300 A 50 50 0 1 1 100 299"/>
        </defs>
        <circle cx="100" cy="300" r="50" stroke="gray" stroke-width="1" fill="none"/>
        <text font-family="Arial" font-size="12" fill="black">
            <textPath href="#circle">圆形路径上的文本</textPath>
        </text>
        
        <!-- 文本对齐 -->
        <text x="300" y="300" font-family="Arial" font-size="14" text-anchor="start" fill="black">左对齐</text>
        <text x="300" y="320" font-family="Arial" font-size="14" text-anchor="middle" fill="black">居中对齐</text>
        <text x="300" y="340" font-family="Arial" font-size="14" text-anchor="end" fill="black">右对齐</text>
        <line x1="300" y1="280" x2="300" y2="360" stroke="red" stroke-width="1"/>
    </svg>
</body>
</html>

8.3.4 文本路径高级应用

创建艺术字效果

结合路径和文本创建特殊效果:

html
<!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>
</head>
<body>
    <h1>SVG艺术字效果</h1>
    
    <svg width="700" height="500" xmlns="http://www.w3.org/2000/svg">
        <!-- 弧形标题文本 -->
        <defs>
            <path id="arc" d="M 100 200 A 150 150 0 0 1 400 200"/>
        </defs>
        <path d="M 100 200 A 150 150 0 0 1 400 200" 
              stroke="lightgray" stroke-width="1" fill="none"/>
        <text font-family="Arial" font-size="24" font-weight="bold" fill="navy">
            <textPath href="#arc" startOffset="50%" text-anchor="middle">
                HTML5 SVG 学习
            </textPath>
        </text>
        
        <!-- 波浪形文本 -->
        <defs>
            <path id="wave2" d="M 50 300 Q 100 250 150 300 Q 200 350 250 300 Q 300 250 350 300 Q 400 350 450 300"/>
        </defs>
        <path d="M 50 300 Q 100 250 150 300 Q 200 350 250 300 Q 300 250 350 300 Q 400 350 450 300" 
              stroke="lightgray" stroke-width="1" fill="none"/>
        <text font-family="Arial" font-size="16" fill="green">
            <textPath href="#wave2">跟随波浪起伏的文本效果</textPath>
        </text>
        
        <!-- 螺旋文本 -->
        <defs>
            <path id="spiral" d="M 550 100 
                                 Q 580 80 600 100 
                                 Q 620 120 600 140 
                                 Q 580 160 550 140 
                                 Q 520 120 550 100 
                                 Q 565 90 575 100 
                                 Q 585 110 575 120 
                                 Q 565 130 550 120 
                                 Q 535 110 550 100"/>
        </defs>
        <path d="M 550 100 
                 Q 580 80 600 100 
                 Q 620 120 600 140 
                 Q 580 160 550 140 
                 Q 520 120 550 100 
                 Q 565 90 575 100 
                 Q 585 110 575 120 
                 Q 565 130 550 120 
                 Q 535 110 550 100" 
              stroke="lightgray" stroke-width="1" fill="none"/>
        <text font-family="Arial" font-size="12" fill="purple">
            <textPath href="#spiral">螺旋路径文本</textPath>
        </text>
        
        <!-- 文本描边效果 -->
        <text x="100" y="450" font-family="Arial" font-size="36" font-weight="bold" 
              stroke="black" stroke-width="2" fill="yellow">描边文本</text>
        
        <!-- 文本阴影效果 -->
        <text x="320" y="455" font-family="Arial" font-size="36" font-weight="bold" fill="gray">阴影文本</text>
        <text x="315" y="450" font-family="Arial" font-size="36" font-weight="bold" fill="blue">阴影文本</text>
    </svg>
</body>
</html>

8.3.5 无障碍访问和语义化

为SVG文本添加无障碍支持

确保SVG文本具有良好的可访问性:

html
<!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>
</head>
<body>
    <h1>SVG无障碍文本示例</h1>
    
    <svg width="600" height="400" xmlns="http://www.w3.org/2000/svg" 
         role="img" aria-labelledby="chart-title" aria-describedby="chart-desc">
        
        <!-- 图表标题 -->
        <title id="chart-title">销售数据图表</title>
        <desc id="chart-desc">显示2023年各季度销售数据的柱状图</desc>
        
        <!-- 图表数据 -->
        <rect x="50" y="100" width="60" height="150" fill="blue" aria-label="第一季度销售额150万"/>
        <text x="80" y="270" font-family="Arial" font-size="12" text-anchor="middle">Q1</text>
        <text x="80" y="85" font-family="Arial" font-size="12" text-anchor="middle">150</text>
        
        <rect x="150" y="80" width="60" height="170" fill="green" aria-label="第二季度销售额170万"/>
        <text x="180" y="270" font-family="Arial" font-size="12" text-anchor="middle">Q2</text>
        <text x="180" y="65" font-family="Arial" font-size="12" text-anchor="middle">170</text>
        
        <rect x="250" y="60" width="60" height="190" fill="red" aria-label="第三季度销售额190万"/>
        <text x="280" y="270" font-family="Arial" font-size="12" text-anchor="middle">Q3</text>
        <text x="280" y="45" font-family="Arial" font-size="12" text-anchor="middle">190</text>
        
        <rect x="350" y="70" width="60" height="180" fill="orange" aria-label="第四季度销售额180万"/>
        <text x="380" y="270" font-family="Arial" font-size="12" text-anchor="middle">Q4</text>
        <text x="380" y="55" font-family="Arial" font-size="12" text-anchor="middle">180</text>
        
        <!-- 坐标轴标签 -->
        <text x="250" y="300" font-family="Arial" font-size="14" text-anchor="middle" 
              role="text" aria-label="横轴标签">季度</text>
        <text x="20" y="180" font-family="Arial" font-size="14" text-anchor="middle" 
              transform="rotate(-90 20 180)" role="text" aria-label="纵轴标签">销售额(万元)</text>
        
        <!-- 图例 -->
        <g role="group" aria-label="图例说明">
            <rect x="450" y="100" width="15" height="15" fill="blue"/>
            <text x="475" y="112" font-family="Arial" font-size="12">Q1销售额</text>
            
            <rect x="450" y="125" width="15" height="15" fill="green"/>
            <text x="475" y="137" font-family="Arial" font-size="12">Q2销售额</text>
            
            <rect x="450" y="150" width="15" height="15" fill="red"/>
            <text x="475" y="162" font-family="Arial" font-size="12">Q3销售额</text>
            
            <rect x="450" y="175" width="15" height="15" fill="orange"/>
            <text x="475" y="187" font-family="Arial" font-size="12">Q4销售额</text>
        </g>
    </svg>
</body>
</html>

关键要点总结

  1. 路径命令:掌握M、L、H、V、Q、C、A、Z等路径命令的使用
  2. 复杂图形:组合多个路径命令创建复杂的矢量图形
  3. 文本元素:使用text和tspan元素实现富文本格式
  4. 文本路径:textPath元素让文本沿着自定义路径排列
  5. 无障碍性:为SVG文本添加适当的ARIA属性和语义标签

参考资源

常见问题解答

Q: 如何创建平滑的曲线路径? A: 使用Q(二次贝塞尔)或C(三次贝塞尔)命令,合理设置控制点位置。

Q: 文本沿路径排列时如何控制起始位置? A: 使用textPath元素的startOffset属性控制文本在路径上的起始位置。

Q: 如何实现文本的垂直居中对齐? A: 使用dominant-baseline属性设置为"middle"或"central"。

Q: SVG路径数据过长时如何优化? A: 使用相对坐标命令(小写字母)和简化路径数据,移除不必要的精度。

Q: 如何确保SVG文本在不同设备上显示一致? A: 使用Web字体或系统通用字体族,避免使用特定的字体名称。