viewport ——表示SVG可见区域的大小
<svg width="500" height="300"></svg>
在<svg>
元素中通过设置其width和height属性来控制SVG的viewport大小。SVG中超出视窗边界的区域会被裁切并且隐藏。
其中width和hegiht的属性值可以直接是一个简单的数字,也可以指定具体的单位。如果没有指定单位,那么将会认其为“像素px”为单位。
SVG支持的长度单位有:em,ex,px,pt,pc,cm,mm,in和百分比。
viewBox——“视区盒子”
更形象的解释就是:SVG就像是我们的显示器屏幕,viewBox就是截屏工具选中的那个框框,
最终的呈现就是把框框中的截屏内容再次在显示器中全屏显示!
viewBox="x, y, width, height" // x:左上角横坐标,y:左上角纵坐标,width:宽度,height:高度
x和y值决定viewBox的左上角,width和height决定视窗的宽高。这里要注意视窗的宽高不一定和父<svg>
元素的宽高一样。<width>
和<height>
值为负数是不合法的。值为0的话会禁止元素的渲染。
注意:视窗的宽度也可以在CSS中设置为任何值。例如:设置width:100%会让SVG视窗在文档中自适应。无论viewBox的值是多少,它会映射为外层SVG元素计算出的宽度值。
我喜欢像Google地图一样通过viewBox把SVG画布形象化。在Google地图中你可以在特定区域缩放;这个区域是唯一可见的,并且在浏览器视窗中按比例增加。然而,你知道地图的剩余部分还在那里,但是不可见因为它超出视窗的边界-被裁切了。
<svg width="400" height="300" viewBox="0,0,40,30" style="border:1px solid #cd0000;">
<rect x="10" y="5" width="20" height="15" fill="#cd0000"/>
</svg>
preserveAspectRatio
强制统一缩放比来保持图形的宽高比。
preserveAspectRatio="xMidYMid meet"
xMidYMid:
viewBox如何与SVG viewport对齐是由两部分组成的,前半部分表示x方向对齐,后半部分表示y方向对齐。
值 | 含义 |
---|---|
xMin | viewport和viewBox左边对齐 |
xMid | viewport和viewBox x轴中心对齐 |
xMax | viewport和viewBox右边对齐 |
YMin | viewport和viewBox上边缘对齐。注意Y是大写。 |
YMid | viewport和viewBox y轴中心点对齐。注意Y是大写。 |
YMax | viewport和viewBox下边缘对齐。注意Y是大写。 |
meet:
如何维持高宽比(如果有)
值 | 含义 |
---|---|
meet | 保持纵横比缩放viewBox适应viewport,受 |
slice | 保持纵横比同时比例小的方向放大填满viewport,攻 |
none | 扭曲纵横比以充分适应viewport,变态 |
注:你可以把meet or slice的值类比于background-size的contain和cover值,meet类似于contain,slice类似于cover。
一旦你设定最外层SVG元素的宽高,浏览器会建立初始视窗坐标系和初始用户坐标系。
- 初始视窗坐标系:一个建立在视窗上的坐标系。原点(0,0)在视窗的左上角
- 初始用户坐标系:
- 建立在SVG画布上的坐标系。这个坐标系一开始和视窗坐标系完全一样-它自己的原点位于视窗左上角。
- 使用viewBox属性,初始用户坐标系统-也称当前坐标系,或使用中的用户空间-可以变成与视窗坐标系不一样的坐标系。
您可以狠狠地点击这里:meet,slice,none功能演示demo
首先,看下SVG代码:
<svg width="400" height="200" viewBox="0 0 200 200" style="border:1px solid #cd0000;">
<rect x="10" y="10" width="150" height="150" fill="#cd0000"/>
</svg>
截取SVG左边一半(200正好宽度400的一般)作为视区,里面有个150*150的红色矩形。
x轴距离:(400-200)/2+10
默认展示如下:
如果我估计没错,默认应该是”xMidYmid meet”效果。
① 如果是meet效果,代码如下:
<svg width="400" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin meet" style="border:1px solid #cd0000;">
<rect x="10" y="10" width="150" height="150" fill="#cd0000"/>
</svg>
截图效果如下:
表现原理为:SVG宽400, 高200,viewBox宽200, 高200。x横轴比例是2, y纵轴比例是1。meet的作用是让viewBox等比例的同时,完全在SVG的viewport中显示。这里,最小比例是纵向的1,所以,实际上viewBox并没有任何的缩放。
我们只要对viewBox属性值做一点小小的修改(200→300),就可以感受到缩放了:
<svg width="400" height="200" viewBox="0 0 200 300" preserveAspectRatio="xMinYMin meet" style="border:1px solid #cd0000;">
<rect x="10" y="10" width="150" height="150" fill="#cd0000"/>
</svg>
此时的显示效果为:
改成300后,viewBox的高度就比viewport的200高,所以,viewBox要想完全适应viewport,就要进行缩放,所以,我们可以上到上面的矩形面积变小了,就是因为缩放的结果(缩放了200/300, 差不多原来的66.7%)。
② 如果是slice, slice本身就有剪切的意思。代码如下:
<svg width="400" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin slice" style="border:1px solid #cd0000;">
<rect x="10" y="10" width="150" height="150" fill="#cd0000"/>
</svg>
效果如下:
slice也是要保持viewBox的纵横比的,不过,其作用是尽量填满viewport。 同样,这里viewBox宽度200,SVG的width是400. 显然,要想最大化充满,viewBox的宽度就需要扩大为原来的两倍。于是,就有了上图viewBox放大两倍后的效果截图。由于viewBox部分区域超出了viewport, 视区之外内容是不可见的,于是就出现了slice所表意的“剪切”效果。
③ 如果是none, 则表示不关心比例,viewBox直接拉伸到最大填满viewport。
效果:
原本好好的一个正方形,现在因为viewBox的拉伸,变成了一个宽高2:1的矩形了。
viewBox的对齐
千言万语不如一个可以自己动手体验的demo实在,您可以狠狠地点击这里:viewBox的对齐各个名称表现感受demo。
截两张图给大家瞅瞅:
无论是meet还是slice,你是不可能在一种状态下同时看到x, y方向上的位移的。因为总会有一个方向是充满viewport的。
为了使文中的内容和解释更形象化,我创建了一个互动演示,你可以任意改变viewBox 和 preserveAspectRatio的值。
在线案例:http://sarasoueidan.com/demos/interactive-svg-coordinate-system/index.html