SVG - 视口和坐标系

387 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

坐标系

SVG 使用的坐标系统(网格系统)和 Canvas的差不多。坐标系是 以左上⻆为 (0,0) 坐标原点,坐标以像素为单位,x 轴正方向是向右,y 轴正方向是向下

svg元素默认宽为 300px, 高为 150px

svg元素和其它元素一样也是有一个坐标空间的,其原点位于元素的左上⻆,被称为初始视口坐标系

svg的 transform 属性可以用来移动、旋转、缩放SVG中的某个元素

如果svg中某个元素用了变形,该元素内部会建立一个新的坐标系统,该元素默认后续所有变化都是基于新创建的坐标系统

SVG坐标系统,在没有明确指定单位时,默认以像素为单位。SVG也支持包括em,rem等在内的其它单位

<svg width="100rem" height="100rem">
  <rect x="0" y="0" width="100" height="100"></rect>
</svg>

视口

视口是 SVG 可⻅的区域(也可以说是SVG画布大小)

可以使用svg元素的width和height属性指定视口的大小

一旦设置了最外层 SVG 元素的宽度和高度,浏览器就会建立初始视口坐标系和初始用户坐标系

视口坐标系

视口坐标系是在视口上建立的坐标系,原点在视口左上⻆的点(0, 0),x轴正向向右,y轴正向下

初始视口坐标系中的一个单位等于视口中的一个像素,该坐标系类似于 HTML 元素的坐标系

用户坐标系

用户坐标系是建立在 SVG 视口上的坐标系,用户坐标系最初与视口坐标系相同——它的原点位于视口的左上⻆

使用viewBox属性,可以修改初始用户坐标系,使其不再与视口坐标系相同

当viewBox和viewPort不一致的时候,在实际渲染的时候,会等比缩放viewBox使其大小和viewPort保持一致

viewBox

viewport是 SVG 画布的大小,而 viewBox 是用来定义用户坐标系中的位置和尺寸

SVG的图形都是绘制到该区域中。用户坐标系可以比视口坐标系更小或更大,也可以在视口内完全或部分 可⻅

# <min-x>和<min-y>确定视图框的左上⻆坐标(不是修改用户坐标系的原点,绘图还是从原来的0,0开始)
# <width><height>确定该视图框的宽度和高度
#  - 宽度和高度不必与父<svg>元素上设置的宽度和高度相同
#  - 宽度和高度负值无效,为 0 是禁用元素的显示
# viewBox = <min-x> <min-y> <width> <height>

如果用户坐标系与视口坐标系具有相同的高宽比,它将viewBox区域拉伸以填充视口区域

当用户坐标系和初始坐标系一致时

<svg
   width="100"
   height="100"
   viewBox="0 0 100 100"
>
  <circle cx="50" cy="50" r="50"></circle>
</svg>

image.png

此时将用户坐标系设置为初始坐标系的1/4

<svg
   width="400"
   height="400"
   viewBox="0 0 100 100"
 >
  <circle cx="50" cy="50" r="50"></circle>
</svg>

image.png

此时可以看到 当坐标系与视口坐标系具有相同的高宽比,它将viewBox区域拉伸以填充视口区域

<!--
	viewBox的 第一个参数 和 第二个参数 可以看成是截取的初始坐标
	viewBox="0 0 100 100" -> 绘图完成后,从(0, 0) 截取到(100, 100)
	viewBox="50 50 100 100" -> 绘图完成后,从(50, 50) 截取到(100, 100)
	再截取后,如果用户坐标系和初始坐标系不一致的时候,等比放大
-->
<svg
   width="400"
   height="400"
   viewBox="50 50 100 100"
 >
  <circle cx="50" cy="50" r="50"></circle>
</svg>

image.png

如果用户坐标系和视口坐标系没有相同的宽高比,可用preserveAspectRatio属性来指定整个用户坐标系统是否在视口内可⻅

<svg
   width="400"
   height="400"
   viewBox="0 0 200 100"
>
  <circle cx="50" cy="50" r="50"></circle>
</svg>

当用户坐标系 和 视口坐标系不一致的时候

  1. 在用户坐标系中进行等比缩放
  2. 将用户坐标系在初始坐标系中垂直和水平居中显示

image.png

preserveAspectRatio

可选值说明
none强制拉伸图形以填充整个视口 --- 不会保持纵横比
xMinYMin图形在视口的最小x和y轴上显示
<svg
   width="400"
   height="400"
   viewBox="0 0 200 100"
   preserveAspectRatio="none"
 >
  <circle cx="50" cy="50" r="50"></circle>
</svg>

image.png

  1. 在用户坐标系中等比缩放
  2. 在不保持纵横比的情况下,缩放图片 以填充整个坐标系
<svg
   width="400"
   height="400"
   viewBox="0 0 200 100"
   preserveAspectRatio="xMinYMin"
 >
  <circle cx="50" cy="50" r="50"></circle>
</svg>

image.png

  1. 在用户坐标系中等比缩放
  2. 用户坐标系和视口坐标系 大小保持一致,但是内部图片不进行缩放