svg viewBox与自适应

12,524 阅读4分钟

前言

在前端布局上经常需要考虑布局的自适应,使用d3与svg绘制图表亦是如此,本文是对使用svg的viewBox属性及preserveAspectRatio属性的总结,可将其应用于图表自适应之中。

什么是viewBox

svg的大小称为viewport(视口),其区域大小即为用户的可视区域。而viewBox则定义了在user space(即用户绘制的区域)上的位置和大小。

The viewBox attribute defines the position and dimension, in user space, of an SVG viewport. ——svg - viewBox

其值为

<svg viewBox="min-x, min-y, width, height">

四个值指定了一个矩形,在user sapce中指定区域,匹配至viewport进行显示。

下面我们进行三种情况的举例,分别为无viewBoxviewBox小于viewportviewBox大于viewport

此几例中先设定viewBox的长宽比等于viewport的长宽比

无viewBox

我们拿此无viewBox的基本图形作为接下来的示例

<svg width="200"
     height="200"
     style="border:1px solid red">

  <rect x="0" y="0" width="50" height="40"/>
  <circle cx="10" cy="20" r="4" fill="white"/>
  
</svg>

红框为svg边框,矩形为50*40,圆半径为4

CodePen打开

接下来我们将基于以上添加viewBox属性进行修改。

viewBox小于viewport

我们在svg中添加一个和即将viewBox一样大的rect,100*100,位置(0, 0)

CodePen打开

接下来设定svg的属性viewBox="0 0 100 100"

CodePen打开

粉色方框用来表示viweBox圈住的范围。可以看到viewBox指定了user space上的(0, 0)位置,用100*100矩形将其圈住,使圈住范围在200*200的viewport上进行显示,因此就像放大了一样。

viewBox大于viewport

当viewBox大于viewport时,所圈住的内容映射在viewport上看起来则缩小

此例中我们设置viewBox="0 0 400 400"

CodePen打开

以上便是viewBox的作用。根据实验结果,如果未设置viewBox,其默认属性值大小应该为"0, 0, viewport宽, viewport高"

什么是preserveAspectRatio

以上内容是viewBox与viewport长宽比例相同情况下的变换场景,但如果不同应该怎么办,如何指定它们的表现,需要的就是preserveAspectRatio属性了。

preserveAspectRatio属性的作用是根据不同的长宽比,指示如何将viewBox适应至viewport。

其语法为:

preserveAspectRatio="<align> [<meetOrSlice>]"

align由[xMin,xMid,xMax]与[YMin,YMid,YMax]两两搭配而成,或者直接取值为none。

meetOrSlice有[meet,slice]可选,当align为none时,此项不用填。

举例:

  • preserveAspectRatio="xMidYMid meet"(默认值)
  • preserveAspectRatio="none"

align值用于表示viewBox与viewport的对齐方式,meetOrSlice用于表示viewBox如何选取长宽比进行缩放,若值为none,则进行强行缩放。

这几个属性可能比较难以理解,推荐大家动手尝试

可通过此页面调试不同值进行查看:

CodePen打开

这里设置viewBox为0,0,300,200,放置粉色矩形长宽为300*200表示viewBox,举例xMidYMid meet、xMidYMid slice、none三种情况

xMidYMid meet

meet使得viewBox的长宽比例被保持,viewBox会去适应viewport大小。

同时xMidYMid meet也是preserveAspectRatio的默认值

xMidYMid slice

当meetOrSlice更改为slice时,viewBox的长宽比例仍然是被保持的,但会使得viewBox尽可能地填满viewport,由此也造成了裁剪效果。

none

当值为none时,我们可以看到viewBox的内容则被强行拉伸去适应viewport

如何应用到svg内容自适应

我们可以利用viewBox完成svg内容的自适应:设置viewBox作为我们的固定绘图大小,svg视口(viewport)为百分比(preserveAspectRatio默认值为xMidYMid meet不用另外设置)。如此,当svg由于窗口大小改变时,其内容也能自适应地缩小或者放大。

<svg style="border:1px solid red" viewBox="0 0 200 200" id="svg-ele">
  <circle cx="100" cy="100" r="60" fill="black" />
</svg>
#svg-ele{
  position: fixed;
  width: 40%;
  height: 40%;
}

如gif图,svg的大小百分比改变,但其内容自适应缩放。

CodePen打开

总结

本文总结了viewBox、preserveAspectRatio及其自适应应用。preserveAspectRatio可能一开始比较难理解,但是动动手做做小实验就可以理解其含义。

以上内容若有不足,还请大佬赐教。

参考资料

理解SVG viewport,viewBox,preserveAspectRatio缩放 —— 张鑫旭
svg - viewBox
svg - preserveAspectRatio

最后给大家推荐一个近期发现的便宜寄快递的平台,官方快递员上门取件,下单有快递员的联系电话后主动联系快递员取件更快!

image.png