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

多媒体:SVG基本形状 - 完整教程与代码示例

一、教程简介

SVG 提供了六种基本形状元素,用于绘制矩形、圆形、椭圆、直线、多边形和折线。这些基本形状是构建复杂 SVG 图形的基础。本教程将详细讲解每种形状的语法、属性和使用方法,并通过丰富的示例展示如何组合这些形状创建各种图形。


二、核心概念

六种基本形状

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

通用样式属性

属性 说明 默认值
fill 填充颜色 #000000
stroke 描边颜色 none
stroke-width 描边宽度 1
stroke-linecap 线端样式 butt
stroke-linejoin 连接样式 miter
opacity 整体透明度 1
fill-opacity 填充透明度 1
stroke-opacity 描边透明度 1

三、语法与用法

rect - 矩形

代码示例

<rect x="10" y="10" width="100" height="50" rx="5" ry="5" />
属性 说明 默认值
x, y 左上角坐标 0
width, height 宽高(必须为非负) 0
rx, ry 圆角半径 0

circle - 圆形

代码示例

<circle cx="100" cy="100" r="50" />
属性 说明 默认值
cx, cy 圆心坐标 0
r 半径(必须为非负) 0

ellipse - 椭圆

代码示例

<ellipse cx="100" cy="100" rx="80" ry="50" />
属性 说明 默认值
cx, cy 圆心坐标 0
rx, ry 水平/垂直半径 0

line - 直线

代码示例

<line x1="0" y1="0" x2="100" y2="100" stroke="black" />
属性 说明 默认值
x1, y1 起点坐标 0
x2, y2 终点坐标 0

注意<line> 必须设置 stroke,否则不可见。

polygon - 多边形

代码示例

<polygon points="100,10 40,198 190,78 10,78 160,198" />

points 属性定义多边形的顶点坐标,首尾自动闭合。

polyline - 折线

代码示例

<polyline points="0,100 50,25 50,75 100,0" />

points 属性定义折线的顶点坐标,不自动闭合。


四、代码示例

示例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;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    .grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 20px;
      max-width: 750px;
    }
    .card {
      background: #161b22;
      border: 1px solid #30363d;
      border-radius: 8px;
      padding: 15px;
      text-align: center;
    }
    .card h3 { color: #58a6ff; font-size: 14px; margin: 0 0 8px; }
    .card code { color: #8b949e; font-size: 11px; }
    svg { background: #0d1117; border-radius: 4px; }
  </style>
</head>
<body>
  <h1>SVG 六种基本形状</h1>
  <div class="grid">
    <!-- rect -->
    <div class="card">
      <h3>rect 矩形</h3>
      <svg width="200" height="150" viewBox="0 0 200 150">
        <rect x="20" y="20" width="160" height="50" fill="#e94560" rx="0" />
        <rect x="20" y="85" width="160" height="50" fill="#58a6ff" rx="15" />
        <text x="100" y="50" text-anchor="middle" fill="#fff" font-size="12">rx=0 直角</text>
        <text x="100" y="115" text-anchor="middle" fill="#fff" font-size="12">rx=15 圆角</text>
      </svg>
      <code>&lt;rect x y width height rx&gt;</code>
    </div>

    <!-- circle -->
    <div class="card">
      <h3>circle 圆形</h3>
      <svg width="200" height="150" viewBox="0 0 200 150">
        <circle cx="60" cy="75" r="45" fill="#3fb950" opacity="0.8" />
        <circle cx="140" cy="75" r="35" fill="#f8b500" opacity="0.8" />
        <circle cx="100" cy="75" r="25" fill="#d2a8ff" opacity="0.8" />
      </svg>
      <code>&lt;circle cx cy r&gt;</code>
    </div>

    <!-- ellipse -->
    <div class="card">
      <h3>ellipse 椭圆</h3>
      <svg width="200" height="150" viewBox="0 0 200 150">
        <ellipse cx="100" cy="75" rx="90" ry="30" fill="#e9456040" stroke="#e94560" stroke-width="2" />
        <ellipse cx="100" cy="75" rx="40" ry="60" fill="#58a6ff40" stroke="#58a6ff" stroke-width="2" />
      </svg>
      <code>&lt;ellipse cx cy rx ry&gt;</code>
    </div>

    <!-- line -->
    <div class="card">
      <h3>line 直线</h3>
      <svg width="200" height="150" viewBox="0 0 200 150">
        <line x1="20" y1="20" x2="180" y2="130" stroke="#e94560" stroke-width="3" />
        <line x1="20" y1="130" x2="180" y2="20" stroke="#58a6ff" stroke-width="3" />
        <line x1="100" y1="10" x2="100" y2="140" stroke="#3fb950" stroke-width="2" stroke-dasharray="5,5" />
      </svg>
      <code>&lt;line x1 y1 x2 y2&gt;</code>
    </div>

    <!-- polygon -->
    <div class="card">
      <h3>polygon 多边形</h3>
      <svg width="200" height="150" viewBox="0 0 200 150">
        <!-- 三角形 -->
        <polygon points="50,15 90,80 10,80" fill="#e94560" opacity="0.7" />
        <!-- 五边形 -->
        <polygon points="150,20 180,55 168,95 132,95 120,55" fill="#58a6ff" opacity="0.7" />
        <!-- 星形 -->
        <polygon points="100,110 110,135 135,135 115,150 122,175 100,160 78,175 85,150 65,135 90,135" fill="#f8b500" opacity="0.7" />
      </svg>
      <code>&lt;polygon points="..."&gt;</code>
    </div>

    <!-- polyline -->
    <div class="card">
      <h3>polyline 折线</h3>
      <svg width="200" height="150" viewBox="0 0 200 150">
        <polyline points="10,130 40,80 70,100 100,40 130,70 160,30 190,60"
                  fill="none" stroke="#3fb950" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" />
        <!-- 数据点 -->
        <g fill="#3fb950">
          <circle cx="10" cy="130" r="3" />
          <circle cx="40" cy="80" r="3" />
          <circle cx="70" cy="100" r="3" />
          <circle cx="100" cy="40" r="3" />
          <circle cx="130" cy="70" r="3" />
          <circle cx="160" cy="30" r="3" />
          <circle cx="190" cy="60" r="3" />
        </g>
      </svg>
      <code>&lt;polyline points="..."&gt;</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;
    }
  </style>
</head>
<body>
  <h1>SVG 形状组合 - 风景画</h1>
  <svg width="700" height="400" viewBox="0 0 700 400" xmlns="http://www.w3.org/2000/svg">
    <defs>
      <linearGradient id="sky" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stop-color="#0f0c29" />
        <stop offset="50%" stop-color="#302b63" />
        <stop offset="100%" stop-color="#24243e" />
      </linearGradient>
      <linearGradient id="grass" x1="0" y1="0" x2="0" y2="1">
        <stop offset="0%" stop-color="#2d5016" />
        <stop offset="100%" stop-color="#1a3a0a" />
      </linearGradient>
    </defs>

    <!-- 天空 -->
    <rect width="700" height="400" fill="url(#sky)" />

    <!-- 星星 -->
    <g fill="#fff" opacity="0.8">
      <circle cx="50" cy="30" r="1.5" />
      <circle cx="150" cy="60" r="1" />
      <circle cx="250" cy="20" r="1.5" />
      <circle cx="380" cy="45" r="1" />
      <circle cx="500" cy="25" r="1.5" />
      <circle cx="600" cy="55" r="1" />
      <circle cx="650" cy="30" r="1.5" />
      <circle cx="100" cy="80" r="1" />
      <circle cx="450" cy="70" r="1" />
    </g>

    <!-- 月亮 -->
    <circle cx="580" cy="70" r="30" fill="#f5f5dc" />
    <circle cx="595" cy="60" r="28" fill="#302b63" />

    <!-- 远山 -->
    <polygon points="0,280 100,180 200,250 300,160 400,220 500,170 600,230 700,190 700,280" fill="#1a1a3e" />

    <!-- 近山 -->
    <polygon points="0,300 80,230 180,270 280,200 380,260 480,210 580,250 700,220 700,300" fill="#2a2a4e" />

    <!-- 地面 -->
    <rect x="0" y="300" width="700" height="100" fill="url(#grass)" />

    <!-- 湖泊 -->
    <ellipse cx="350" cy="340" rx="200" ry="30" fill="#1a3a5c" opacity="0.8" />
    <ellipse cx="350" cy="335" rx="180" ry="15" fill="#2a5a8c" opacity="0.4" />

    <!-- 房子 -->
    <g>
      <!-- 墙壁 -->
      <rect x="100" y="260" width="80" height="40" fill="#4a4a6a" />
      <!-- 屋顶 -->
      <polygon points="90,260 140,230 190,260" fill="#e94560" />
      <!-- 门 -->
      <rect x="125" y="278" width="20" height="22" fill="#2a1a0a" rx="2" />
      <!-- 窗户 -->
      <rect x="108" y="268" width="12" height="12" fill="#ffd700" opacity="0.8" rx="1" />
      <rect x="158" y="268" width="12" height="12" fill="#ffd700" opacity="0.8" rx="1" />
      <!-- 烟囱 -->
      <rect x="155" y="237" width="10" height="23" fill="#5a3a3a" />
    </g>

    <!-- 树 -->
    <g>
      <!-- 树干 -->
      <rect x="295" y="265" width="10" height="35" fill="#5a3a1a" />
      <!-- 树冠 -->
      <polygon points="300,220 270,270 330,270" fill="#2d6b16" />
      <polygon points="300,235 275,265 325,265" fill="#3a8b1e" />

      <rect x="545" y="260" width="10" height="40" fill="#5a3a1a" />
      <polygon points="550,210 520,265 580,265" fill="#2d6b16" />
      <polygon points="550,225 525,260 575,260" fill="#3a8b1e" />
    </g>

    <!-- 栅栏 -->
    <g stroke="#8b7355" stroke-width="2" fill="#8b7355">
      <line x1="400" y1="280" x2="400" y2="300" />
      <line x1="420" y1="280" x2="420" y2="300" />
      <line x1="440" y1="280" x2="440" y2="300" />
      <line x1="460" y1="280" x2="460" y2="300" />
      <line x1="480" y1="280" x2="480" y2="300" />
      <line x1="395" y1="285" x2="485" y2="285" stroke-width="1.5" />
      <line x1="395" y1="295" x2="485" y2="295" stroke-width="1.5" />
    </g>

    <!-- 小路 -->
    <polyline points="140,300 160,320 200,340 260,350 350,345"
              fill="none" stroke="#6b5a3a" stroke-width="8" stroke-linecap="round" stroke-linejoin="round" opacity="0.5" />
  </svg>
</body>
</html>

五、浏览器兼容性

所有现代浏览器完整支持 SVG 六种基本形状,包括 IE9+。


六、注意事项与最佳实践

1. line 必须设置 stroke

代码示例

<!-- 不可见:line 默认无描边 -->
<line x1="0" y1="0" x2="100" y2="100" />

<!-- 可见 -->
<line x1="0" y1="0" x2="100" y2="100" stroke="black" stroke-width="2" />

2. polyline 的 fill

代码示例

<!-- 不闭合折线:fill="none" -->
<polyline points="10,10 50,50 90,10" fill="none" stroke="black" />

<!-- 默认 fill="black" 会填充闭合区域 -->
<polyline points="10,10 50,50 90,10" stroke="black" />

3. 使用 g 元素分组

代码示例

<g transform="translate(100, 100)" fill="#58a6ff">
  <rect x="0" y="0" width="50" height="30" />
  <circle cx="25" cy="50" r="15" />
</g>

4. 负值宽高

SVG 中 rect 的 width 和 height 不允许为负值,否则图形不显示。


七、代码规范示例

代码示例

<!-- 推荐:使用语义化的 id 和注释 -->
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <!-- 图标:首页 -->
  <g id="home-icon" fill="none" stroke="currentColor" stroke-width="2">
    <polygon points="100,30 170,90 155,90 155,160 115,160 115,120 85,120 85,160 45,160 45,90 30,90" />
  </g>
</svg>

<!-- 推荐:使用 CSS 类复用样式 -->
<style>
  .shape-primary { fill: #58a6ff; stroke: #1f6feb; stroke-width: 2; }
  .shape-danger { fill: #e94560; stroke: #c9302c; stroke-width: 2; }
</style>
<svg viewBox="0 0 200 100">
  <rect class="shape-primary" x="10" y="10" width="80" height="80" rx="8" />
  <circle class="shape-danger" cx="150" cy="50" r="35" />
</svg>

八、常见问题与解决方案

常见问题

polygon 和 polyline 的区别?

polygon 自动闭合首尾点,polyline 不闭合。

如何绘制圆角矩形?

使用 rxry 属性:

代码示例

<rect x="10" y="10" width="100" height="50" rx="10" ry="10" />
如何绘制正多边形?

计算顶点坐标:

代码示例

function regularPolygonPoints(cx, cy, r, sides) {
  const points = [];
  for (let i = 0; i < sides; i++) {
    const angle = (i / sides) * Math.PI * 2 - Math.PI / 2;
    points.push(`${cx + r * Math.cos(angle)},${cy + r * Math.sin(angle)}`);
  }
  return points.join(' ');
}

九、总结

SVG 六种基本形状是构建矢量图形的基础,关键要点:

  • rect:矩形,支持圆角 rx/ry

  • circle:圆形,通过 cx/cy/r 定义

  • ellipse:椭圆,通过 rx/ry 定义两个半径

  • line:直线,必须设置 stroke 才可见

  • polygon:多边形,自动闭合

  • polyline:折线,不自动闭合,注意 fill 默认值

  • 通用样式:fill、stroke、opacity 等属性适用于所有形状

下一教程将介绍 SVG 路径的绘制。

标签: SVG形状 矩形 圆形 椭圆 多边形 折线

本文涉及AI创作

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

list快速访问

上一篇: 多媒体:SVG简介 - 完整教程与代码示例 下一篇: 多媒体:SVG路径 - 完整教程与代码示例

poll相关推荐