SVG 使用的坐标系统是笛卡尔坐标系,以左上角为原点 (0,0),x 轴向右增长,y 轴向下增长。理解 SVG 的坐标系统对于精确控制图形的位置和尺寸至关重要。
SVG 使用笛卡尔坐标系统:
(0, 0)视口是 SVG 的可见区域,由 width 和 height 属性定义:
<svg width="200" height="100">
<!-- 视口尺寸为 200x100 像素 -->
</svg>用户坐标系是 SVG 内部使用的坐标系统,可以通过 viewBox 属性定义。
viewBox 是 SVG 中至关重要的属性,它定义了 SVG 画布上可见区域的坐标系。viewBox 允许独立于 SVG 的 width 和 height 来定义图形的坐标空间。这创建了一个用户坐标系,使得图形可以独立于视口尺寸进行缩放。
viewBox="min-x min-y width height"min-x: 可视区域左上角的 x 坐标min-y: 可视区域左上角的 y 坐标width: 可视区域的宽度height: 可视区域的高度<svg width="200" height="100" viewBox="0 0 400 200" style="border: 1px solid #ccc;">
<!-- 这个圆形在 400x200 的坐标系中绘制 -->
<circle cx="200" cy="100" r="80" fill="lightblue"/>
</svg>示例中:
viewBox定义400x200的内部坐标系(用户坐标系),而 SVG 的实际尺寸是200x100(视口)。浏览器会自动将400x200的viewBox缩放到200x100的视口中,相当于将图形缩小了一半。
通过 viewBox 可以实现图形的缩放:
<svg width="200" height="200" viewBox="0 0 100 100">
<!-- viewBox 比视口小,图形会被放大 -->
<circle cx="50" cy="50" r="40" fill="blue"/>
</svg>
<svg width="200" height="200" viewBox="0 0 400 400">
<!-- viewBox 比视口大,图形会被缩小 -->
<circle cx="200" cy="200" r="160" fill="red"/>
</svg>通过调整 viewBox 的 min-x 和 min-y 可以实现平移:
<svg width="200" height="200" viewBox="50 50 100 100">
<!-- 只显示 viewBox 指定的区域 -->
<rect x="0" y="0" width="200" height="200" fill="lightblue"/>
</svg>preserveAspectRatio 属性用于控制当 viewBox 的宽高比与 SVG 视口的宽高比不匹配时,图形如何缩放和对齐。默认值为 xMidYMid meet。
preserveAspectRatio="align meetOrSlice"| 值 | 描述 |
|---|---|
xMinYMin | 左上对齐 |
xMidYMin | 水平居中,顶部对齐 |
xMaxYMin | 右上对齐 |
xMinYMid | 左对齐,垂直居中 |
xMidYMid | 水平和垂直居中 |
xMaxYMid | 右对齐,垂直居中 |
xMinYMax | 左下对齐 |
xMidYMax | 水平居中,底部对齐 |
xMaxYMax | 右下对齐 |
| 值 | 描述 |
|---|---|
meet | 保持宽高比,缩放以适应视口(默认) |
slice | 保持宽高比,缩放以填充视口,可能裁剪内容 |
none | 不保持宽高比,拉伸以填充视口 |
<svg width="200" height="100" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
<!-- 居中对齐,保持宽高比 -->
<rect x="0" y="0" width="100" height="100" fill="blue"/>
</svg>
<svg width="200" height="100" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice">
<!-- 居中对齐,填充视口,可能裁剪 -->
<rect x="0" y="0" width="100" height="100" fill="red"/>
</svg>
<svg width="200" height="100" viewBox="0 0 100 100" preserveAspectRatio="none">
<!-- 拉伸以填充视口,不保持宽高比 -->
<rect x="0" y="0" width="100" height="100" fill="green"/>
</svg>当一个 <svg> 元素嵌套在另一个 <svg> 元素内部时,会创建一个新的坐标系。内部 <svg> 的 x 和 y 属性定义了它在父坐标系中的位置。
<svg width="200" height="200" style="border: 1px solid black;">
<!-- 外部 SVG -->
<rect x="10" y="10" width="180" height="180" fill="lightgray" />
<!-- 嵌套 SVG,创建新的视口和坐标系 -->
<svg x="50" y="50" width="100" height="100" viewBox="0 0 50 50">
<!-- 这个圆形是在 50x50 的 viewBox 中绘制的,但会根据 100x100 的视口放大 -->
<circle cx="25" cy="25" r="25" fill="blue" />
</svg>
</svg>嵌套 SVG 常用于:
<!DOCTYPE html>
<html>
<head>
<style>
.responsive-svg {
width: 100%;
height: auto;
}
</style>
</head>
<body>
<!-- 使用 viewBox 实现 SVG 响应式 -->
<svg class="responsive-svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="blue"/>
</svg>
</body>
</html><svg width="600" height="400" viewBox="0 0 1200 800">
<!-- 大尺寸地图,自动缩放到 600x400 -->
<rect x="0" y="0" width="1200" height="800" fill="#f0f0f0"/>
<!-- 地图内容 -->
<circle cx="600" cy="400" r="50" fill="red"/>
<text x="600" y="410" text-anchor="middle">地图中心</text>
</svg><div style="display: flex; gap: 20px;">
<!-- 原始大小 -->
<svg width="200" height="200" viewBox="0 0 200 200">
<circle cx="100" cy="100" r="80" fill="blue"/>
</svg>
<!-- 缩略图 -->
<svg width="100" height="100" viewBox="0 0 200 200">
<circle cx="100" cy="100" r="80" fill="blue"/>
</svg>
<!-- 更小的缩略图 -->
<svg width="50" height="50" viewBox="0 0 200 200">
<circle cx="100" cy="100" r="80" fill="blue"/>
</svg>
</div>width/height: 定义 SVG 在页面上的显示尺寸(视口)viewBox: 定义 SVG 内部的坐标系统(用户坐标系)preserveAspectRatio 控制对齐方式设置 width: 100% 和 height: auto,并使用 viewBox:
svg {
width: 100%;
height: auto;
}可以,负数坐标表示原点左上方的区域:
<svg width="200" height="200" viewBox="-100 -100 200 200">
<circle cx="0" cy="0" r="50" fill="blue"/>
</svg>