svg的viewBox是常用的属性,但是这个属性经常令人迷惑,搞不清楚他的具体行为。这篇文章详细解释viewBox属性,并且由此引出svg图像的裁剪。
viewBox的字面意思是视野窗口,可以理解为怎样显示一个svg的一部分。举个例子,<svg width="200" height="300" viewBox="0 0 400 600" style="border: 1px solid black;">
<rect x="0" y="0" width="200" height="200" stroke="#ff0000" fill="rgba(0,0,255,.3)" stroke-width="5"/>
</svg>
效果如下:
可以看到,1px代表2个单位,就是在这个svg中画一个宽度200个点位正方形,实际上表示的是100px。再看如下代码:
<svg width="200" height="300" viewBox="100 100 400 600" style="border: 1px solid black;">
<rect x="0" y="0" width="200" height="200" stroke="#ff0000" fill="rgba(0,0,255,.3)" stroke-width="5"/>
</svg>
效果如下:
明显正方形被从中心点100,100的地方截取了。到这里我们很容易得到viewBox四个参数的含义:前两个参数表示以该点为起始点展示svg图形,后两个参数表示视口相对于viewBox的缩放。 从代码中我们发现,svg定义的宽高比,正好等于view定义的缩放比,就是200/300正好等于400/600。如果不相等会出现什么情况呢?考虑如下代码。
<svg width="200" height="300" viewBox="0 0 400 800" style="border: 1px solid black;"> <rect x="0" y="0" width="200" height="200" stroke="#ff0000" fill="rgba(0,0,255,.3)" stroke-width="5"/> </svg>
和代码
<svg width="200" height="300" viewBox="0 0 400 400" style="border: 1px solid black;"> <rect x="0" y="0" width="200" height="200" stroke="#ff0000" fill="rgba(0,0,255,.3)" stroke-width="5"/> </svg>
的区别。结果如下:
明明正方形的起始点是(0,0)为什么不是从左上角开始的呢?其实这也好理解,考虑一下css的background-size: contain;属性如果图片的尺寸和div的尺寸宽高比不一样的情况,下面是我做的例子:
svg和css好多地方是相通的,可以理解问在默认情况下如果svg定义的宽高比和viewBox的宽高比不一致,svg就按照background-size: contain;的方式将svg放进去。如果我们想自定义放置的方式怎么办呢?例如:无论如何我都想让svg从左上角开始,不管宽高比是否适配。这就是要介绍的下面的svg属性:preserveAspectRatio。
语法:preserveAspectRatio=align meetOrSlice
排列方式是(xMin,xMid,xMax)和(yMin,yMid,yMax)的组合,例如我想让他总是从左上角开始就定义:preserveAspectRatio="xMinYMin meet",想一下css的排列方式。都是上中下,左中右的排列,svg也是一样的。这里有需要注意的地方,如果viewBox的高度比较高,也就是例子中viewBox="0 0 200 400"的情况,对y的定义是无效的,因为这时viewBox在y方向是铺满的。
<svg width="200" height="300" viewBox="0 0 200 400" preserveAspectRatio="xMinYMid meet" style="border: 1px solid black;"> <rect x="0" y="0" width="100" height="100" stroke="#ff0000" fill="rgba(0,0,255,.3)" stroke-width="5"/> </svg>
同理宽度较宽的情况一样,x方向不起作用。但是语法必须是(xMin,xMid,xMax)和(yMin,yMid,yMax)的组合这是令人诧异的。
假如不想全部显示,如果宽高比不匹配就剪切到一部分,就将preserveAspectRatio中的meet换成slice,图像就会背剪切掉。
<svg width="200" height="300" viewBox="0 0 200 400" preserveAspectRatio="xMinYMid slice" style="border: 1px solid black;"> <rect x="0" y="0" width="100" height="100" stroke="#ff0000" fill="rgba(0,0,255,.3)" stroke-width="5"/> </svg>
效果如图:
其实不管meet还是slice,对于svg画的图是不变形的,也就是说正方形,不会变成长方形,这里就有比css高级一点的地方,可以使用preserveAspectRatio的none属性,让图像变形,当然实际情况是让图像拉伸的情景很少。
<svg width="200" height="300" viewBox="0 0 200 400" preserveAspectRatio="none" style="border: 1px solid black;"> <rect x="0" y="0" width="100" height="100" stroke="#ff0000" fill="rgba(0,0,255,.3)" stroke-width="5"/> </svg>
效果如下:
可以看到图像变形了,可以拉伸和压缩。相信这篇文章能让你对svg的viewBox有进一步了解,在实际项目中对你有所帮助,谢谢观看,能力有限,难免有所疏漏,敬请指正。