pin_drop当前位置:知识文库 ❯ 图文

多媒体:SVG路径 - 完整教程与代码示例

一、教程简介

SVG <path> 是最强大的绘图元素,通过 d 属性中的命令可以绘制任意形状的路径。path 命令包括移动(M)、直线(L)、水平线(H)、垂直线(V)、闭合(Z)、弧线(A)、二次贝塞尔曲线(Q)和三次贝塞尔曲线(C)等。本教程将详细讲解所有路径命令的语法和使用方法。


二、核心概念

路径命令概览

命令 说明 参数
M/m 移动到 x,y
L/l 画线到 x,y
H/h 水平线到 x
V/v 垂直线到 y
Z/z 闭合路径
C/c 三次贝塞尔曲线 x1,y1 x2,y2 x,y
S/s 平滑三次贝塞尔 x2,y2 x,y
Q/q 二次贝塞尔曲线 x1,y1 x,y
T/t 平滑二次贝塞尔 x,y
A/a 弧线 rx,ry rotation large-arc sweep x,y

提示大写命令使用绝对坐标,小写命令使用相对坐标。


三、语法与用法

M - 移动到(Move To)

代码示例

<path d="M 10 10" />  <!-- 绝对坐标 -->
<path d="m 10 10" />  <!-- 相对坐标 -->

L - 画线到(Line To)

代码示例

<path d="M 10 10 L 100 100" />

H/V - 水平/垂直线

代码示例

<path d="M 10 10 H 100" />  <!-- 水平线到 x=100 -->
<path d="M 10 10 V 100" />  <!-- 垂直线到 y=100 -->

Z - 闭合路径

代码示例

<path d="M 10 10 L 100 10 L 100 100 Z" />

C - 三次贝塞尔曲线

代码示例

<path d="M 10 10 C 20 0, 80 0, 90 10" />
<!-- C x1,y1 x2,y2 x,y -->

S - 平滑三次贝塞尔

代码示例

<path d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" />
<!-- S x2,y2 x,y(x1,y1 自动镜像计算) -->

Q - 二次贝塞尔曲线

代码示例

<path d="M 10 80 Q 95 10 180 80" />
<!-- Q x1,y1 x,y -->

T - 平滑二次贝塞尔

代码示例

<path d="M 10 80 Q 52 10 95 80 T 180 80" />
<!-- T x,y(控制点自动镜像计算) -->

A - 弧线

代码示例

<path d="M 10 80 A 45 45, 0, 0, 0, 125 125" />
<!-- A rx ry, x-rotation, large-arc-flag, sweep-flag, x y -->
参数 说明
rx, ry 椭圆半径
x-rotation 椭圆旋转角度
large-arc-flag 0=小弧,1=大弧
sweep-flag 0=逆时针,1=顺时针
x, y 终点坐标

四、代码示例

示例1:路径命令全面演示

代码示例

<!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>
  <style>
    body {
      margin: 0;
      padding: 20px;
      background: #0d1117;
      color: #c9d1d9;
      font-family: 'Segoe UI', sans-serif;
    }
    .grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 15px;
      max-width: 750px;
      margin: 0 auto;
    }
    .card {
      background: #161b22;
      border: 1px solid #30363d;
      border-radius: 8px;
      padding: 12px;
      text-align: center;
    }
    .card h3 { color: #58a6ff; font-size: 13px; margin: 0 0 5px; }
    .card code { color: #8b949e; font-size: 10px; display: block; margin-top: 5px; }
    svg { background: #0d1117; border-radius: 4px; }
  </style>
</head>
<body>
  <h1 style="text-align:center">SVG 路径命令全面演示</h1>
  <div class="grid">
    <div class="card">
      <h3>M L Z 直线闭合</h3>
      <svg width="220" height="120" viewBox="0 0 220 120">
        <path d="M 20 20 L 200 20 L 200 100 L 20 100 Z" fill="#e9456040" stroke="#e94560" stroke-width="2" />
      </svg>
      <code>M 20 20 L 200 20 L 200 100 L 20 100 Z</code>
    </div>

    <div class="card">
      <h3>H V 水平垂直线</h3>
      <svg width="220" height="120" viewBox="0 0 220 120">
        <path d="M 20 20 H 200 V 100 H 20 Z" fill="#58a6ff40" stroke="#58a6ff" stroke-width="2" />
      </svg>
      <code>M 20 20 H 200 V 100 H 20 Z</code>
    </div>

    <div class="card">
      <h3>Q 二次贝塞尔</h3>
      <svg width="220" height="120" viewBox="0 0 220 120">
        <path d="M 20 100 Q 110 10 200 100" fill="#3fb95040" stroke="#3fb950" stroke-width="2" />
        <circle cx="110" cy="10" r="3" fill="#e94560" />
        <line x1="20" y1="100" x2="110" y2="10" stroke="#30363d" stroke-dasharray="4" />
        <line x1="110" y1="10" x2="200" y2="100" stroke="#30363d" stroke-dasharray="4" />
      </svg>
      <code>M 20 100 Q 110 10 200 100</code>
    </div>

    <div class="card">
      <h3>C 三次贝塞尔</h3>
      <svg width="220" height="120" viewBox="0 0 220 120">
        <path d="M 20 100 C 60 10, 160 10, 200 100" fill="#f8b50040" stroke="#f8b500" stroke-width="2" />
        <circle cx="60" cy="10" r="3" fill="#e94560" />
        <circle cx="160" cy="10" r="3" fill="#e94560" />
        <line x1="20" y1="100" x2="60" y2="10" stroke="#30363d" stroke-dasharray="4" />
        <line x1="160" y1="10" x2="200" y2="100" stroke="#30363d" stroke-dasharray="4" />
      </svg>
      <code>M 20 100 C 60 10, 160 10, 200 100</code>
    </div>

    <div class="card">
      <h3>S 平滑三次贝塞尔</h3>
      <svg width="220" height="120" viewBox="0 0 220 120">
        <path d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 210 80" fill="#d2a8ff40" stroke="#d2a8ff" stroke-width="2" />
      </svg>
      <code>M 10 80 C 40 10, 65 10, 95 80 S 150 150, 210 80</code>
    </div>

    <div class="card">
      <h3>T 平滑二次贝塞尔</h3>
      <svg width="220" height="120" viewBox="0 0 220 120">
        <path d="M 10 80 Q 52 10, 95 80 T 180 80" fill="#f7816640" stroke="#f78166" stroke-width="2" />
      </svg>
      <code>M 10 80 Q 52 10, 95 80 T 180 80</code>
    </div>

    <div class="card">
      <h3>A 弧线 (小弧/顺时针)</h3>
      <svg width="220" height="120" viewBox="0 0 220 120">
        <path d="M 30 80 A 45 45, 0, 0, 1, 190 80" fill="none" stroke="#58a6ff" stroke-width="2" />
      </svg>
      <code>A 45 45, 0, 0, 1, 190 80</code>
    </div>

    <div class="card">
      <h3>A 弧线 (大弧/逆时针)</h3>
      <svg width="220" height="120" viewBox="0 0 220 120">
        <path d="M 30 80 A 45 45, 0, 1, 0, 190 80" fill="none" stroke="#e94560" stroke-width="2" />
      </svg>
      <code>A 45 45, 0, 1, 0, 190 80</code>
    </div>

    <div class="card">
      <h3>组合路径 - 心形</h3>
      <svg width="220" height="120" viewBox="0 0 220 120">
        <path d="M 110 100 C 110 80, 60 50, 60 70 C 60 90, 110 110, 110 120 C 110 110, 160 90, 160 70 C 160 50, 110 80, 110 100 Z"
              fill="#e94560" opacity="0.7" />
      </svg>
      <code>心形路径 (C 命令组合)</code>
    </div>
  </div>
</body>
</html>

示例2:路径实战 - 图标绘制

代码示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>路径实战 - 图标绘制</title>
  <style>
    body {
      margin: 0;
      padding: 20px;
      background: #1a1a2e;
      color: #eee;
      font-family: 'Segoe UI', sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    .icons {
      display: flex;
      gap: 30px;
      flex-wrap: wrap;
      justify-content: center;
    }
    .icon-card {
      text-align: center;
    }
    .icon-card p { margin: 5px 0 0; font-size: 12px; color: #8b949e; }
    svg { transition: transform 0.3s; }
    svg:hover { transform: scale(1.1); }
  </style>
</head>
<body>
  <h1>SVG 路径实战 - 图标绘制</h1>
  <div class="icons">
    <!-- 搜索图标 -->
    <div class="icon-card">
      <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#58a6ff" stroke-width="2" stroke-linecap="round">
        <circle cx="11" cy="11" r="8" />
        <path d="M 21 21 L 16.65 16.65" />
      </svg>
      <p>搜索</p>
    </div>

    <!-- 主页图标 -->
    <div class="icon-card">
      <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#3fb950" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M 3 12 L 12 3 L 21 12" />
        <path d="M 5 10 V 20 H 10 V 14 H 14 V 20 H 19 V 10" />
      </svg>
      <p>主页</p>
    </div>

    <!-- 用户图标 -->
    <div class="icon-card">
      <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#f8b500" stroke-width="2" stroke-linecap="round">
        <circle cx="12" cy="8" r="4" />
        <path d="M 4 21 C 4 16, 8 14, 12 14 C 16 14, 20 16, 20 21" />
      </svg>
      <p>用户</p>
    </div>

    <!-- 心形图标 -->
    <div class="icon-card">
      <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#e94560" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M 12 21 C 12 21, 3 14, 3 8.5 C 3 5.4, 5.4 3, 8.5 3 C 10.2 3, 11.8 3.8, 12 5 C 12.2 3.8, 13.8 3, 15.5 3 C 18.6 3, 21 5.4, 21 8.5 C 21 14, 12 21, 12 21 Z" />
      </svg>
      <p>心形</p>
    </div>

    <!-- 邮件图标 -->
    <div class="icon-card">
      <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#d2a8ff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <rect x="2" y="4" width="20" height="16" rx="2" />
        <path d="M 2 7 L 12 13 L 22 7" />
      </svg>
      <p>邮件</p>
    </div>

    <!-- 设置图标 -->
    <div class="icon-card">
      <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#f78166" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <circle cx="12" cy="12" r="3" />
        <path d="M 19.4 15 A 1.65 1.65 0 0 0 19.68 17 L 19.68 17 A 2 2 0 0 1 17.68 20.32 L 17.68 20.32 A 1.65 1.65 0 0 0 15 19.4 A 1.65 1.65 0 0 0 13.32 20.32 L 13.32 20.32 A 2 2 0 0 1 10.68 20.32 L 10.68 20.32 A 1.65 1.65 0 0 0 9 19.4 A 1.65 1.65 0 0 0 7.32 20.32 L 7.32 20.32 A 2 2 0 0 1 4.32 17.68 L 4.32 17.68 A 1.65 1.65 0 0 0 4.6 15 A 1.65 1.65 0 0 0 4.32 13.32 L 4.32 13.32 A 2 2 0 0 1 6.32 10.68 L 6.32 10.68 A 1.65 1.65 0 0 0 9 10.6 A 1.65 1.65 0 0 0 10.68 9.68 L 10.68 9.68 A 2 2 0 0 1 13.32 9.68 L 13.32 9.68 A 1.65 1.65 0 0 0 15 10.6 A 1.65 1.65 0 0 0 16.68 9.68 L 16.68 9.68 A 2 2 0 0 1 19.68 12.32 L 19.68 12.32 A 1.65 1.65 0 0 0 19.4 15 Z" />
      </svg>
      <p>设置</p>
    </div>
  </div>
</body>
</html>

五、浏览器兼容性

所有现代浏览器完整支持 SVG path 的所有命令。


六、注意事项与最佳实践

1. 绝对与相对坐标

代码示例

<!-- 绝对坐标:大写命令 -->
<path d="M 10 10 L 100 100" />

<!-- 相对坐标:小写命令 -->
<path d="M 10 10 l 90 90" />

2. 命令可省略空格

代码示例

<!-- 完整写法 -->
<path d="M 10 10 L 100 100" />

<!-- 省略空格(逗号分隔) -->
<path d="M10,10 L100,100" />

<!-- 连续相同命令可省略命令字母 -->
<path d="M10 10 L100 10 100 100 10 100 Z" />

3. 弧线命令的四个组合

large-arc sweep 效果
0 0 小弧 + 逆时针
0 1 小弧 + 顺时针
1 0 大弧 + 逆时针
1 1 大弧 + 顺时针

4. 路径闭合

代码示例

<!-- Z 闭合路径,画线回到起点 -->
<path d="M 10 10 L 100 10 L 100 100 Z" />

七、代码规范示例

代码示例

<!-- 推荐:路径代码格式化 -->
<path d="
  M 10 10
  L 100 10
  L 100 100
  L 10 100
  Z
" />

<!-- 推荐:使用语义化注释 -->
<path d="
  M 50 20       <!-- 顶部中心 -->
  L 80 80       <!-- 右下 -->
  L 20 80       <!-- 左下 -->
  Z             <!-- 闭合三角形 -->
" fill="#58a6ff" />

八、常见问题与解决方案

常见问题

弧线命令太难理解?

使用在线 SVG 路径编辑器(如 SVG Path Editor),可视化调整参数。

如何将基本形状转换为 path?

可以通过等价转换将基本形状转换为 path:

代码示例

<!-- rect → path -->
<rect x="10" y="10" width="100" height="50" rx="5" />
<!-- 等价于 -->
<path d="M 15 10 H 105 Q 110 10 110 15 V 55 Q 110 60 105 60 H 15 Q 10 60 10 55 V 15 Q 10 10 15 10 Z" />

<!-- circle → path -->
<circle cx="50" cy="50" r="30" />
<!-- 等价于 -->
<path d="M 50 20 A 30 30 0 1 0 50 80 A 30 30 0 1 0 50 20 Z" />
如何获取 SVG 路径的总长度?

使用 JavaScript 的 getTotalLength() 方法:

代码示例

const path = document.querySelector('path');
const totalLength = path.getTotalLength();
console.log('路径总长度:', totalLength);

九、总结

SVG path 是最强大的绘图元素,关键要点:

  • M/m:移动画笔,不画线

  • L/l/H/h/V/v:画直线

  • Z/z:闭合路径

  • C/c/S/s:三次贝塞尔曲线

  • Q/q/T/t:二次贝塞尔曲线

  • A/a:弧线,4种组合控制弧线方向

  • 大小写:大写绝对坐标,小写相对坐标

  • 实战应用:图标、复杂形状、自定义图形

下一教程将介绍 SVG 文本的绘制。

标签: SVG路径 path命令 贝塞尔曲线 弧线 图标绘制

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: 多媒体:SVG基本形状 - 完整教程与代码示例 下一篇: 多媒体:SVG文本 - 完整教程与代码示例

poll相关推荐