理解SVG中的 viewport,viewBox, preserveAspectRatio
理解viewport
该属性表示的是SVG可见区域的大小。或者也可以叫画布的大小。就好比我们的电脑屏幕,我们只能看到我们电脑屏幕的可视区里面的内容,但是看不到电脑屏幕之外的内容。比如如下代码:
1 | <svg width="200" height="200" style="border: 1px solid red"></svg> |
上述代码设置了svg的画布大小为200px*200px, 如果没有带单位的话,该单位默认是 px(像素)。当然也有其他单位:
- em: 相对于父元素的字体大小。
- ex: 相对于小写字母的 ‘x’ 的高度(不常用)
- px: 像素(在支持css2的图形系统中,每英寸为96像素)。
- pt: 点(1/72英寸)
- pc: 12点(1/6英寸)。
- cm: 厘米
- mm: 毫米
- in: 英寸
svg元素的width和height还可以为百分比,当我们的svg元素嵌套在一个div里面去的话,那么它的百分比是相对于外层的div元素的宽度和高度进行计算的。当然如果我们的svg元素为根元素的话,那么它的百分比是相对于窗口的尺寸来计算的
1 | <div style="width:400px;height:400px; border: 1px solid red; "> |
如果我们没有给svg设置宽度和高度的话,它默认的宽度为300px,高度为150px
理解默认用户坐标
在svg中有一个默认的坐标系统,其中 水平坐标(x坐标)向右递增的,垂直坐标(y坐标)是向下递增的。原点坐标是(0, 0). 该坐标系统类似于我们数学几何中的坐标。
比如我们现在建立一个200px宽,200px高的视口,然后我们在里面绘制一个矩形,该矩形左上角在坐标(10, 10)的位置,该矩形的宽度为50px, 高度为 50px,基本代码如下:
1 | <svg style="border: 1px solid red;" width="200" height="200"> |
理解viewBox
- viewBox=”x, y, w, h”; 该属性的含义是可视区盒子,即画布的可视区。
- viewport 和 viewBox 分别有自己的坐标系,默认情况下,该两个坐标系是重合的,即转换关系是 1:1。
- x: 指左上角的坐标,y: 左上角的纵坐标,w: 指宽度,h: 指高度
画布(viewport)、可视区(viewBox) 的宽度的高度相等情况
1 | <div style="width:100%;display:inline-block;"> |
如上代码,svg的画布大小,宽度为400px,高度为200px,然后使用viewBox属性定义画布的可视区的大小宽度也是400px,高度也是200px, 因此该两个坐标系是重合的,因此我们使用 rect 来创建矩形的话,定义宽度和高度分别为100px,x轴和y轴的偏移位置为10px
画布不变,可视区的宽度减小的情况
比如如下代码,可视区的宽度减少100px,1
2
3
4
5<div style="width:100%;display:inline-block;">
<svg style="border: 1px solid red;" width="400" height="200" viewBox="0,0,300,200">
<rect x="10" y="10" width="100" height="100" style="stroke: black; fill:none;"></rect>
</svg>
</div>
画布不变,可视区的高度减小的情况
1 | <svg style="float:left;border: 1px solid red;" width="200" height="200" viewBox="0,0,200,100"> |
如上可以看到,矩形向下偏移的距离 = 200 - 100 / 2 + 10 = 60px; 因此我们可以看到我们的下面的div元素 margin-top:60px; 就可以对齐了。
可视区不变,画布宽度变小
如果可视区不变的话,画布宽度减少的话,那么矩形也要等比例缩小,比如如下代码:1
2
3
4<svg style="float:left;border: 1px solid red;" width="100" height="200" viewBox="0,0,200,200">
<rect x="0" y="0" width="100" height="100" style="stroke: black; fill:none;"></rect>
</svg>
<div style="float:left; margin-left: 20px; border: 1px solid red;width:100px;height:200px;margin-top:50px"></div>
如上可以看到,矩形本来大小是 100px*100px,现在画布的宽度改成100px了,那么矩形也变成原来的一半了,至于向下移动距离的计算 = 200 - 100 / 2 = 50px;
可视区不变,画布的高度变小
可视区不变,画布高度变小的话,那么矩形也要等比例缩放;如下代码所示:1
2
3
4
5
6<div style="width:100%;display:inline-block;">
<svg style="float:left;border: 1px solid red;" width="200" height="80" viewBox="0,0,200,200">
<rect x="0" y="0" width="100" height="100" style="stroke: black; fill:none;"></rect>
</svg>
</div>
<div style="margin-top:10px;border: 1px solid red;width:200px;height:80px;margin-left:60px"></div>
可视区宽度和高度大于画布的宽度和高度
1 | <svg style="float:left;border: 1px solid red;" width="45" height="135" viewBox="0,0,200,200"> |
如果可视区宽度和高度大于画布的宽度和高度的话,那么 矩形的宽度和高度的计算方式以 宽度和高度最小的那个来等比例计算,什么意思呢?我们如上的画布的宽度是45px,高度是135px,那么宽度小于高度,因此需要按照45px来计算,因此计算方式 =1
2
3200 100
--- = ----
45 x
理解 preserveAspectRatio
该属性的作用是:它允许我们指定被缩放的图像相对视口的对齐方式。基本的使用方法如下所示:
preserveAspectRatio = “alignment [meet | slice]”
其中 alignment 指定轴和位置,默认值为 preserveAspectRatio = “xMidYMid meet”;
preserveAspectRatio 该属性是应用在SVG上,且和viewBox属性配合一起使用的。viewBox属性值可以指明是否可以等比例缩放(宽高比相同的情况下),以扩展到viewport指定的大小区域中。
第二个参数有3个值可选,分别为:meet 和 slice 和 none。
- meet 的含义是:viewBox保持等比例缩放,整个viewBox在viewport中都是可见的。在满足2个约束的条件基础上,尽可能的放大viewBox,当viewport的宽高比和viewBox的宽高比不匹配的时候,那么取宽高比中较小的那个。
- slice 的含义是:修剪viewBox保持等比例缩放,整个viewport区域会被viewBox覆盖。在满足2个约束的条件基础之上,尽可能的缩小viewBox,当viewport的宽高比和viewBox的宽高比不匹配时,取宽高缩放比中比较大的那个。
- none 的含义是:不强制等比例缩放,尽量以viewBox和viewport以实际的宽高比来缩放图形,尽量把宽度和高度扩展到这个viewport上。最后的结果就会使图像变模糊。
- preserveAspectRatio=”xMinYMin meet”情况
强制缩放比例,xMin:viewBox的x轴和viewport的x轴最左边对齐,YMin:viewBox的y轴和viewport的y轴最左边对齐。
1 | <svg |
preserveAspectRatio=”xMinYMid meet”情况下
强制缩放比例,xMin:viewBox的x轴和viewport的x轴最左边对齐,YMid:viewBox的y轴和viewport的y轴中点对齐。preserveAspectRatio=”xMinYMax meet”情况下
强制缩放比例,xMin:viewBox的x轴和viewport的x轴最左边对齐,YMax:viewBox的y轴和viewport的y轴最下边对齐preserveAspectRatio=”xMidYMin meet”情况下
强制缩放比例,xMid:viewBox的x轴的中心和viewport的x轴中心对齐,yMin: viewBox的Y轴最上方和viewport的y轴最上方对齐。preserveAspectRatio=”xMidYMid meet”
强制等比例缩放,xMid:viewBox的x轴中点和viewport的x轴中点对齐,YMid: viewBox的y轴中点 和 viewport的y轴中点对齐。