SVG 坐标系统

深入理解SVG坐标系统,掌握视口、画布、viewBox的关系。这是SVG最核心的概念之一,理解它对后续学习至关重要。 坐标系统是 SVG 最容易让人困惑的概念,但也是最重要的。搞不懂它,后面的路径、变换都会云里雾里。

这一部分我们来彻底搞清楚 SVG 的坐标系统。

核心概念

SVG 有三个相关的概念:

概念英文说明
视口viewportSVG 在页面上的实际大小
画布canvasSVG 内部的坐标空间
viewBoxviewBox定义画布上哪部分显示在视口里

听起来有点绕?别急,我们一个一个来。

视口(Viewport)

视口就是 SVG 在网页上占据的区域。由 widthheight 属性决定。

视口: 200×100
<svg width="200" height="100">
  <!-- 视口大小是 200×100 像素 -->
</svg>

视口可以用 CSS 单位:

<svg width="100%" height="300">
  <!-- 宽度跟随父容器 -->
</svg>

画布(Canvas)

画布是 SVG 内部的坐标空间。默认情况下,画布大小等于视口大小。

坐标 (10,10) 坐标 (150,50)
<svg width="200" height="100">
  <rect x="10" y="10" width="50" height="30" fill="#e74c3c"/>
  <circle cx="150" cy="50" r="30" fill="#2ecc71"/>
</svg>

坐标原点在左上角:

  • x 向右增大
  • y 向下增大

viewBox 属性

viewBox 是 SVG 最强大的属性。它定义了画布上哪部分区域显示在视口里。

格式:viewBox="min-x min-y width height"

viewBox="0 0 200 200"

画布大,显示范围大

viewBox="0 0 100 100"

画布和视口一样大

viewBox="0 0 50 50"

画布小,内容放大

理解方式:把 viewBox 想象成一个取景框。

  • viewBox 比视口大 → 取景框大,内容缩小
  • viewBox 比视口小 → 取景框小,内容放大
  • viewBox 有偏移 → 取景框移动,显示不同区域

viewBox 偏移效果

viewBox 的前两个参数可以移动取景框的位置。

viewBox="0 0 100 100"

viewBox="25 25 50 50"

viewBox="50 50 50 50"

<svg width="100" height="100" viewBox="25 25 50 50">
  <circle cx="50" cy="50" r="45" fill="#e74c3c"/>
</svg>

这个例子中:

  • 圆心在 (50, 50)
  • viewBox 从 (25, 25) 开始,宽高 50
  • 所以圆心正好在视口中心

preserveAspectRatio 属性

当 viewBox 和视口比例不一致时,怎么对齐?这就需要 preserveAspectRatio

格式:preserveAspectRatio="align meetOrSlice"

align 值

说明
xMinYMin左上对齐
xMidYMid居中对齐(默认)
xMaxYMax右下对齐

meetOrSlice 值

说明
meet保持比例,完整显示(默认)
slice保持比例,填满视口,可能裁剪

meet(默认)

slice

none(拉伸)

<svg width="150" height="100" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
  <rect width="100" height="100" fill="#3498db"/>
</svg>

响应式 SVG

利用 viewBox,可以轻松实现响应式 SVG:

响应式 SVG

调整浏览器窗口大小试试

<svg viewBox="0 0 100 50" style="width: 100%; height: auto;">
  <rect x="5" y="5" width="90" height="40" rx="5" fill="#3498db"/>
  <text x="50" y="30" text-anchor="middle" fill="white">响应式 SVG</text>
</svg>

关键点:

  • 设置 width: 100%
  • 不设置固定 height,用 height: auto
  • viewBox 定义内部坐标

小结

  • 视口:SVG 在页面上的实际大小
  • 画布:SVG 内部的坐标空间
  • viewBox:定义画布上哪部分显示
  • preserveAspectRatio:比例不一致时的对齐方式