Skip to content

SVG 基本图形

SVG(Scalable Vector Graphics)使用 XML 标记语言描述矢量图形,支持矩形、圆形、椭圆、线条、折线和多边形等基本图形元素。每个图形都可以通过丰富的属性进行样式控制,包括填充、描边、透明度等。本节将详细介绍 SVG 基本图形的使用方法。

前置知识

阅读本节前,建议先了解:Canvas 性能优化

基础概念

SVG 图形元素是声明式的——你描述要绘制什么图形,浏览器负责渲染。与 Canvas 不同,SVG 元素可以直接被 CSS 样式化,可以用 JavaScript 交互,且天然支持无损缩放。

SVG 基本图形元素一览

元素说明常用属性
<rect>矩形x, y, width, height, rx, ry
<circle>圆形cx, cy, r
<ellipse>椭圆cx, cy, rx, ry
<line>直线x1, y1, x2, y2
<polyline>折线points
<polygon>多边形points

语法

SVG 根元素

html
<svg width="400" height="300" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg">
  <!-- 图形内容 -->
</svg>

viewBox 属性

viewBox 定义了 SVG 的坐标系统和可视区域:

html
<!-- viewBox="minX minY width height" -->
<svg width="200" height="200" viewBox="0 0 100 100">
  <!-- SVG 逻辑空间是 100x100,但渲染为 200x200 -->
  <circle cx="50" cy="50" r="40" fill="#4285f4"/>
</svg>

详细说明

rect - 矩形

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>SVG 矩形</title>
  <style>
    svg { border: 1px solid #ccc; display: block; margin: 10px 0; }
  </style>
</head>
<body>
  <h1>SVG rect 矩形</h1>

  <svg width="500" height="300" viewBox="0 0 500 300">
    <!-- 基本矩形 -->
    <rect x="20" y="20" width="120" height="80" fill="#4285f4"/>

    <!-- 带圆角的矩形 -->
    <rect x="170" y="20" width="120" height="80"
          rx="10" ry="10" fill="#34a853"/>

    <!-- 只描边的矩形 -->
    <rect x="320" y="20" width="120" height="80"
          fill="none" stroke="#ea4335" stroke-width="3"/>

    <!-- 半透明矩形 -->
    <rect x="20" y="140" width="120" height="80"
          fill="rgba(66, 133, 244, 0.5)" stroke="#4285f4" stroke-width="2"/>

    <!-- 透明度矩形 -->
    <rect x="170" y="140" width="120" height="80"
          fill="#9c27b0" opacity="0.3" stroke="#9c27b0" stroke-width="2"/>

    <!-- 大圆角矩形 -->
    <rect x="320" y="140" width="120" height="80"
          rx="40" ry="40" fill="#ff5722"/>
  </svg>
</body>
</html>

rect 属性

属性说明默认值
x左上角 X 坐标0
y左上角 Y 坐标0
width宽度必填
height高度必填
rxX 方向圆角半径0
ryY 方向圆角半径0

circle - 圆形

html
<svg width="400" height="200" viewBox="0 0 400 200">
  <!-- 实心圆 -->
  <circle cx="60" cy="80" r="50" fill="#4285f4"/>

  <!-- 描边圆 -->
  <circle cx="200" cy="80" r="50"
          fill="none" stroke="#34a853" stroke-width="3"/>

  <!-- 渐变圆 -->
  <defs>
    <radialGradient id="circleGrad" cx="40%" cy="40%">
      <stop offset="0%" stop-color="#ffffff"/>
      <stop offset="100%" stop-color="#ea4335"/>
    </radialGradient>
  </defs>
  <circle cx="340" cy="80" r="50" fill="url(#circleGrad)"/>
</svg>

circle 属性

属性说明默认值
cx圆心 X 坐标0
cy圆心 Y 坐标0
r半径必填

ellipse - 椭圆

html
<svg width="400" height="200" viewBox="0 0 400 200">
  <!-- 水平椭圆 -->
  <ellipse cx="100" cy="100" rx="80" ry="40" fill="#4285f4"/>

  <!-- 垂直椭圆 -->
  <ellipse cx="250" cy="100" rx="40" ry="70" fill="#34a853"/>

  <!-- 描边椭圆 -->
  <ellipse cx="370" cy="100" rx="25" ry="25"
           fill="none" stroke="#ea4335" stroke-width="3"/>
</svg>

ellipse 属性

属性说明默认值
cx中心 X 坐标0
cy中心 Y 坐标0
rxX 轴半径必填
ryY 轴半径必填

line - 直线

html
<svg width="400" height="200" viewBox="0 0 400 200">
  <!-- 基本直线 -->
  <line x1="20" y1="20" x2="200" y2="100"
        stroke="#4285f4" stroke-width="2"/>

  <!-- 粗线 -->
  <line x1="220" y1="20" x2="380" y2="100"
        stroke="#ea4335" stroke-width="5"
        stroke-linecap="round"/>

  <!-- 虚线 -->
  <line x1="20" y1="150" x2="380" y2="150"
        stroke="#34a853" stroke-width="2"
        stroke-dasharray="10, 5"/>
</svg>

polyline - 折线

html
<svg width="400" height="200" viewBox="0 0 400 200">
  <!-- 折线(不闭合) -->
  <polyline points="20,150 60,50 100,120 140,30 180,100 220,60 260,130 300,40"
            fill="none" stroke="#4285f4" stroke-width="2"
            stroke-linejoin="round" stroke-linecap="round"/>
</svg>

polygon - 多边形

html
<svg width="500" height="300" viewBox="0 0 500 300">
  <!-- 三角形 -->
  <polygon points="100,20 180,160 20,160" fill="#4285f4"/>

  <!-- 五角星 -->
  <polygon points="280,20 300,90 375,90 315,135 335,205 280,165 225,205 245,135 185,90 260,90"
           fill="#fbbc05" stroke="#ea4335" stroke-width="1"/>

  <!-- 六边形 -->
  <polygon points="450,50 490,75 490,125 450,150 410,125 410,75"
           fill="#34a853" opacity="0.8"/>
</svg>

填充与描边

fill 属性

html
<!-- 纯色填充 -->
<rect fill="#4285f4"/>

<!-- 无填充 -->
<rect fill="none"/>

<!-- 渐变填充 -->
<rect fill="url(#myGradient)"/>

<!-- 图案填充 -->
<rect fill="url(#myPattern)"/>

<!-- 半透明填充 -->
<rect fill="rgba(66, 133, 244, 0.5)"/>

stroke 属性

html
<svg width="400" height="200" viewBox="0 0 400 200">
  <!-- 描边宽度 -->
  <rect x="10" y="10" width="60" height="40" stroke="#4285f4" stroke-width="1"/>
  <rect x="90" y="10" width="60" height="40" stroke="#4285f4" stroke-width="3"/>
  <rect x="170" y="10" width="60" height="40" stroke="#4285f4" stroke-width="5"/>

  <!-- 描边端点 -->
  <line x1="10" y1="80" x2="100" y2="80" stroke="#ea4335" stroke-width="5" stroke-linecap="butt"/>
  <line x1="120" y1="80" x2="210" y2="80" stroke="#ea4335" stroke-width="5" stroke-linecap="round"/>
  <line x1="230" y1="80" x2="320" y2="80" stroke="#ea4335" stroke-width="5" stroke-linecap="square"/>

  <!-- 描边连接 -->
  <polyline points="10,130 50,100 90,130" fill="none" stroke="#34a853" stroke-width="5" stroke-linejoin="miter"/>
  <polyline points="120,130 160,100 200,130" fill="none" stroke="#34a853" stroke-width="5" stroke-linejoin="round"/>
  <polyline points="230,130 270,100 310,130" fill="none" stroke="#34a853" stroke-width="5" stroke-linejoin="bevel"/>

  <!-- 虚线样式 -->
  <line x1="10" y1="170" x2="350" y2="170" stroke="#9c27b0" stroke-width="2" stroke-dasharray="10,5"/>
  <line x1="10" y1="190" x2="350" y2="190" stroke="#9c27b0" stroke-width="2" stroke-dasharray="5,3,2"/>
</svg>

样式属性速查表

属性说明可选值
fill填充颜色颜色值、noneurl()
fill-opacity填充透明度0 ~ 1
stroke描边颜色颜色值、none
stroke-width描边宽度数值
stroke-opacity描边透明度0 ~ 1
stroke-linecap端点样式buttroundsquare
stroke-linejoin连接样式miterroundbevel
stroke-dasharray虚线模式数值列表
opacity整体透明度0 ~ 1

实战示例

示例 1:SVG 图标绘制

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>SVG 图标</title>
  <style>
    svg { border: 1px solid #ccc; margin: 10px; }
  </style>
</head>
<body>
  <h1>SVG 图标绘制</h1>

  <!-- 首页图标 -->
  <svg width="48" height="48" viewBox="0 0 48 48">
    <path d="M24 4L4 20h6v20h10V28h8v12h10V20h6L24 4z" fill="#4285f4"/>
  </svg>

  <!-- 搜索图标 -->
  <svg width="48" height="48" viewBox="0 0 48 48">
    <circle cx="20" cy="20" r="12" fill="none" stroke="#34a853" stroke-width="4"/>
    <line x1="28" y1="28" x2="42" y2="42" stroke="#34a853" stroke-width="4" stroke-linecap="round"/>
  </svg>

  <!-- 设置图标(齿轮) -->
  <svg width="48" height="48" viewBox="0 0 48 48">
    <path d="M24 16a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm0 12a4 4 0 1 1 0-8 4 4 0 0 1 0 8z" fill="#ea4335"/>
    <path d="M38.86 25.94l-2.68-.74a14.07 14.07 0 0 0 0-4.4l2.68-.74a1 1 0 0 0 .72-1.22l-2.56-4.43a1 1 0 0 0-1.18-.44l-2.5 1.24a13.86 13.86 0 0 0-3.12-1.8l-.38-2.78A1 1 0 0 0 28.84 10h-5.68a1 1 0 0 0-1 .88l-.38 2.78a13.86 13.86 0 0 0-3.12 1.8l-2.5-1.24a1 1 0 0 0-1.18.44l-2.56 4.43a1 1 0 0 0 .72 1.22l2.68.74a14.07 14.07 0 0 0 0 4.4l-2.68.74a1 1 0 0 0-.72 1.22l2.56 4.43a1 1 0 0 0 1.18.44l2.5-1.24a13.86 13.86 0 0 0 3.12 1.8l.38 2.78a1 1 0 0 0 1 .88h5.68a1 1 0 0 0 1-.88l.38-2.78a13.86 13.86 0 0 0 3.12-1.8l2.5 1.24a1 1 0 0 0 1.18-.44l2.56-4.43a1 1 0 0 0-.72-1.22z"
          fill="#ea4335"/>
  </svg>
</body>
</html>

示例 2:SVG 响应式设计

html
<!-- 使用 viewBox 实现响应式 SVG -->
<svg width="100%" height="auto" viewBox="0 0 400 300" preserveAspectRatio="xMidYMid meet">
  <rect x="20" y="20" width="160" height="100" rx="10" fill="#4285f4"/>
  <circle cx="300" cy="70" r="60" fill="#34a853"/>
  <polygon points="200,160 260,280 140,280" fill="#ea4335"/>
</svg>

preserveAspectRatio 选项

说明
xMidYMid meet等比缩放,居中显示(默认)
xMidYMid slice等比缩放,裁剪溢出
none拉伸填满容器
xMinYMin meet等比缩放,左上对齐

注意事项

1. SVG 是 XML 格式

所有属性必须正确闭合,标签必须成对:

html
<!-- 正确 -->
<rect x="10" y="10" width="100" height="50"/>

<!-- 错误:未闭合 -->
<rect x="10" y="10" width="100" height="50">

<!-- 错误:自闭合用错 -->
<rect x="10" y="10" width="100" height="50"></Rect> <!-- 大小写错误 -->

2. fill 的默认值

SVG 图形默认 fill="black",如果只需要描边,必须设置 fill="none"

html
<!-- 错误:只设置了 stroke,但 fill 默认是黑色 -->
<circle cx="50" cy="50" r="40" stroke="#4285f4" stroke-width="2"/>

<!-- 正确 -->
<circle cx="50" cy="50" r="40" fill="none" stroke="#4285f4" stroke-width="2"/>

最佳实践

1. 使用 CSS 样式化 SVG

html
<style>
  .icon {
    fill: currentColor;
    stroke: none;
    transition: fill 0.2s;
  }
  .icon:hover {
    fill: #ea4335;
  }
</style>

<svg class="icon" width="24" height="24" viewBox="0 0 24 24">
  <path d="M12 2L2 12h3v8h6v-5h2v5h6v-8h3L12 2z"/>
</svg>

2. 使用语义化结构

html
<svg viewBox="0 0 400 300" role="img" aria-label="柱状图">
  <title>月度销售额</title>
  <desc>2024 年上半年销售额柱状图</desc>

  <g class="chart">
    <rect x="50" y="100" width="40" height="150" fill="#4285f4"/>
    <rect x="110" y="80" width="40" height="170" fill="#34a853"/>
    <rect x="170" y="120" width="40" height="130" fill="#ea4335"/>
    <rect x="230" y="60" width="40" height="190" fill="#fbbc05"/>
  </g>
</svg>

下一节

继续学习:SVG 路径

参考链接