这一篇是讲 SVG 的坐标系统,在这以前若是你对 SVG 的基础知识还不是很了解,能够先点这里学习 深刻理解 SVG 系列(一) —— SVG 基础。html
和不少计算机绘图所使用的坐标系统同样,SVG 也使用了网格坐标系统。这种坐标系有以下几个特色:segmentfault
X 轴
的正方向向右
,从 0,0 点开始向右, x 逐渐增大。Y 轴
的正方向向下
,从 0,0 点开始向下, y 逐渐增大。<svg width="100" height="100" style="outline: 2px solid red"> <rect x="0" y="0" width="50" height="50" fill='green'/> </svg>
以 0,0 为起始点,画一个 100 * 100 的矩形
上面咱们提到了画布和视窗分别对应两个坐标系,一个视窗坐标系,一个用户坐标系。这两个坐标系都具备咱们上面提到的网格坐标系的几个特色。svg
这两个坐标系一开始是彻底重合的,它们的原点和坐标都是彻底一致的,也就是说初始用户坐标系的原点就位于视窗的左上角,也是 X 轴正向向右,Y 轴正向向下。学习
虽然一开始它们是两个彻底同样的坐标系,但既然是两个坐标系,就意味着它们能够是不同的。你能够经过 viewBox 去改变这种默认对齐的方式,接下来的内容会讲到。spa
以前的章节中,咱们全部的 SVG 内容看起来都像是基于视图坐标系来绘制的,由于初始视窗坐标系和初始用户坐标系彻底相同,但在这一节中,咱们会经过 viewBox 来声明本身的用户坐标系。3d
viewBox 是用来把 SVG 内容绘制到画布上的坐标系。它的字面意思是视图盒子,只有出如今这个盒子区域里面的 SVG 内容才能被看到,你能够理解为 SVG 图形真正的可见区域。code
viewBox = <min-x> <min-y> <width> <height>
viewBox 接收四个参数值,分别是 min-x
,min-y
,width
,height
。htm
min-x
和 min-y
决定了 viewBox 的左上角,width
和 height
决定了 viewBox 的宽和高。注意 width 或 height 若是设置成 0
,会禁止元素的渲染。blog
<svg width="100" height="100" viewBox="0 0 50 50"> <!-- SVG content --> </svg>
设置 viewBox="0 0 50 50"
以后会发生什么?ci
经过改变 min-x 和 min-y 的值能够将 viewBox 声明的区域进行平移。
以坐标点 0,0 为圆心,半径为 50px 画一个圆,咱们只能看到圆的 1/4,如图一:
<svg width=100 height=100 style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
图一
经过设置 viewBox="-50 -50 100 100"
,咱们能够看到一整个圆。以下图:
<svg width=100 height=100 style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
图二
经过 viewBox 的 min-x
和 min-y
两个参数,咱们将 viewBox 声明的区域分别向左和上进行了平移,这时咱们以 0,0 为圆心,半径为 50 画圆,正好可以将整个圆显示到 viwBox 声明的区域中,而后再将这个坐标系映射到 100px * 100px 的视窗中,就大功告成了。
经过改变 width 和 height 的值能够缩放 viewBox 声明的区域。
<svg width=100 height=100 style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
当 viewBox 的宽高小于视窗的宽高时,至关于放大。
<svg width=100 height=100 viewBox="0 0 50 50" style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
当 viewBox 的宽高大于视窗的宽高时,至关于缩小。
<svg width=100 height=100 viewBox="0 0 200 200" style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
由于多设备适配的需求,不少时候咱们指望 SVG 图形可以在不一样的屏幕上放大或缩小,可是咱们又不但愿每次都去修改 <svg>
的 width
和 height
,这时百分比就很是有用了。
若是给视窗设置 width: 100%
和 height: 100%
,那么视窗的宽高就由它父元素的宽高决定,咱们能够经过调整其父元素的宽高来放大和缩小 SVG 视窗,而不用修改 <svg>
的 width 和 height。仅仅是这样还不够,咱们还须要经过 viewBox 来将 SVG 图形放大到整个视窗区域。
<div style="width:100px; height:100px;"> // 你能够试着经过修改 div 的宽高来改变 SVG 图形的大小 <svg width="100%" height="100%" style="outline: 2px solid red" viewBox="0 0 100 100"> <rect x="0" y="0" width="100" height="100" fill="green"/> </svg> </div>
利用 viewBox 实现上半圆
<svg width=100 height=100 viewBox="-50 -100 100 100" style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
在纸上画出 viewBox 声明的区域,以下图:
橙色区域为 viewBox 声明的区域,从粉色的区域移动到橙色区域能够得出 viewBox 的 min-x = -50 min-y = -100,在这个区域只有上半圆可见,所以咱们最后看到的也就只是这个上半圆。
请参考第一题,在纸上画出下面 SVG 的坐标系,在坐标系上画出每一个元素,以及 viewBox 的区域。
<svg width=100 height=100 viewBox="0 -50 100 100" style="outline: 2px solid red"> <circle cx=0 cy=0 r=50 fill="green"/> </svg>
preserveAspectRatio 属性用来强制统一缩放比,以保持图形的宽高比。
若是 viewBox 的宽高比和 SVG 视窗的宽高比不一样,那么在拉伸 viewBox 来适应视窗的时候,就可能致使 SVG 图形发生扭曲。这个时候 preserveAspectRatio 就派上用场了。
preserveAspectRatio = <align> <meetOrSlice>?
align
表示 viewBox 如何与 viewport 对齐。meetOrSlice
是可选的,表示如何保持宽高比。align
align 的值有不少,为了方便理解,咱们先把它最基本的值拆分出来,以下:
值 | 含义 |
---|---|
none | 经过拉伸 viewBox 来适应整个视窗,无论宽高比 |
xMin | viewBox 和 viewport 左边缘对齐 |
xMid | viewBox 和 viewport x 轴中心对齐 |
xMax | viewBox 和 viewport 右边缘对齐 |
YMin | viewBox 和 viewport 上边缘对齐 |
YMid | viewBox 和 viewport y 轴中心对齐 |
YMax | viewBox 和 viewport 下边缘对齐 |
而后再自由组合 x,y 就能能够了,好比:
xMinYMin => 左-上对齐 xMidYmid => 中-中对齐
meetOrSlice
值 | 含义 |
---|---|
meet | 保持宽高比缩放 viewBox 以适应 viewport,相似于 background-size: contain |
slice | 保持宽高比同时比例小的方向放大填满 viewport,相似于 background-size: cover |
<svg width="200" height="100" viewBox="0 0 100 100" style="outline: 2px solid red"> <rect x=10 y=10 width=50 height=50 fill="green"/> </svg>
在上面的例子中,咱们并无设置 preserveAspectRatio ,可是根据咱们以前讲过的知识,不难发如今 <svg>
上做用着一个隐形的 preserveAspectRatio="xMidYMid meet"
。
<svg width="200" height="100" viewBox="0 0 100 100" style="outline: 2px solid red" preserveAspectRatio="xMidYMid meet"> <rect x=10 y=10 width=50 height=50 fill="green"/> </svg>
那么 preserveAspectRatio="xMidYMid meet"
是如何做用在 SVG 上的呢?请看下面的图:
上图中 viewport 宽 200 高 100,viewBox 宽 100 高 100, x 横轴比例是 2, y 纵轴比例是 1。xMidYMid
让 viewBox 和 viewPort 的中心对齐,和 viewport y 轴上边缘对齐。meet
的做用是让 viewBox 保持宽高比的同时,彻底在 viewport 中显示。
由于这里最小的纵向比例是 1 ,因此 viewBox 没有任何的缩放。
为了更好的去感觉缩放,咱们将 viewBox 的宽度从 100 调整到 300,其它保持不变。
<svg width="200" height="100" viewBox="0 0 300 100" style="outline: 2px solid red" preserveAspectRatio="xMinYMin meet"> <rect x=10 y=10 width=50 height=50 fill="green"/> </svg>
这时 viewBox 的宽度超过 viewport 的宽度了(如图一),因此 viewBox 就会缩小以适应 viewport,由于 meet 会让 viewBox 保持比例来进行缩放,因此你能够想象成按住viewBox 的右下角,缩小 viewBox 至 viewport 的大小 (如图二)。
说完了 meet
下面咱们再来讲说 slice, slice 虽然会保持宽高比进行缩放,可是会在比例小的方向放大填满 viewport。好比设置 viewBox 宽 100 高 100,viewport 宽 200 高 100,在 viewport 的 x 轴方向还有空间,因此会将 viewBox 在横轴上进行放大,结果就是咱们的好好的正方形被拉成了矩形。
<svg width="200" height="100" viewBox="0 0 100 100" style="outline: 2px solid red" preserveAspectRatio="xMidYMid slice"> <rect x=10 y=10 width=50 height=50 fill="green"/> </svg>
在学习 SVG 的过程当中,动手画图真的很是的重要。这也是为何我一直尝试图解 SVG,在以前的练习中也要求你们去画图的缘由。画图可以帮助你去理解 SVG 的坐标系,理解每个元素或者每个属性在坐标系中是怎样体现出来的。因此但愿你们在学习 SVG 的过程当中,多去动手画图,最后达到可以“裸写” SVG 的境界!