svg之viewbox缩放

先看个示例

代码如下:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>svg-viewbox</title>
	<style>
	body {
		text-align: center;
	}
	svg {
		margin-top: 100px;
	}
	</style>
</head>
<body>
<svg width="100px" height="200px" style="background:#889cee">
  <circle cx="50" cy="50" r="50" fill="#ff0036"></circle>
</svg>
</body>
</html>

在一个宽为100px,高为200px的画布上,以坐标(50,50)为圆点,50为半径画了一个圆。结果如图所示:
image

但在实际的过程中,根据不同的业务场景,可以需要对画布的大小做出调整,比如我们把画布大小调整为宽50px,高100px,那实际的效果如图所示:
image

根据这个结果我们看到里面的内容根据画布的调整被截断了,显然这个不是我们想要的结果,我们想在改变画布的同时,里面的内容也会跟着自动调整缩放,这时viewbox上场了。

用viewbox缩放解决

我们先给初始代码加上viewbox属性,并将viewbox的值设置和画布的大小1:1。

viewBox 的四个参数分别代表:最小X轴数值;最小y轴数值;宽度;高度。

一般情况,前面2个参数不需要调整,为0就可以,除非你需要视口在画布中发生位移。

<svg width="100px" height="200px" viewbox="0 0 100 200" style="background:#889cee">
  <circle cx="50" cy="50" r="50" fill="#ff0036"></circle>
</svg>

运行代码后,显示效果跟初始的一张图没有什么区别。

但是当我们把画布修改为宽50px,高100px的时候,显示发生了变化

<svg width="50px" height="100px" viewbox="0 0 100 200" style="background:#889cee">
  <circle cx="50" cy="50" r="50" fill="#ff0036"></circle>
</svg>

image

如图所示,里面的内容跟着画布大小的变化发生了缩放,从而实现了我们的功能。

viewbox分析

之所以能缩放,是因为svg的特性,在默认情况下,会调整viewbox的大小,当画布大小调整时,viewbox会自动缩放正好能放进svg里。

拿上面的例子:
image
蓝色框是视口的大小,绿色框是内容圆的大小,当画布大小改变的时候,viewbox需要调整到正好大小放到svg里,所以我们整个显示就缩放了。

这就是视口不变,画布发生变化的情况。我们再看下一下画布不变,视口大小发生改变的情况。

<svg width="100px" height="200px" viewbox="0 0 50 100" style="background:#889cee">
  <circle cx="50" cy="50" r="50" fill="#ff0036"></circle>
</svg>

image

如上图,画布的大小是初始大小,视口的大小即是图里面的蓝色框区域,宽50px,高为100px。按照viewbox需要调整到刚好放到svg里,那么蓝色框区域框着的内容区域就会扩大占满画布。也即是如图所示:
image

viewbox之preserveAspectRatio属性

viewbox 默认这个属性的值为:preserveAspectRatio="xMidYMid meet"

preserveAspectRatio 第一个参数有九个可选值,用来表示视口的对齐方式,以左上角为原点,Min表示靠近原点,Mid表示居中,Max 表示远离原点。

xMinYMin,
xMinYMid,
xMinYMax,
xMidYMin,
xMidYMid,
xMidYMax,
xMaxYMin,
xMaxYMid,
xMaxYMax

上面的例子,当把 viewbox 改为宽高都为100,并且加上 preserveAspectRatio 属性,值为 xMaxYMax:

<svg width="100px" height="200px" viewbox="0 0 100 100" preserveAspectRatio="xMaxYMax" style="background:#889cee">
  <circle cx="50" cy="50" r="50" fill="#ff0036"></circle>
</svg>

image

我们发现视口是离原点最远对齐的,而不是 preserveAspectRatio 的默认值为居中对齐。

第二个参数: meetslice or none

  • meet 就是前面那种自动调整viewbox可以在 svg 画布中完全展示(以画布的最小边为界,不会超过最小边大小)。
  • slice 就是调整viewbox可以撑满 svg 画布(以画布最大边为界,可能会超过最小边,但不会超过最大边)。

改变 preserveAspectRatio 的值为 slice,如下:

<svg width="100px" height="200px" viewbox="0 0 100 100" preserveAspectRatio="xMaxYMax slice" style="background:#889cee">
  <circle cx="50" cy="50" r="50" fill="#ff0036"></circle>
</svg>

image

如上图,对其方式是离原点最远对齐,并且第二个参数为 slice 表示视图会撑满视图最大的边。也就是 viewbox 的高100会以画布的高200做调整。

  • none 表示 viewbox 会被拉伸到和 svg 画布相同尺寸,里面的内容也会被等比拉伸,不能维持原有比例
<svg width="100px" height="200px" viewbox="0 0 100 100" preserveAspectRatio="none" style="background:#889cee">
  <circle cx="50" cy="50" r="50" fill="#ff0036"></circle>
</svg>

image

参考

posted @ 2023-01-29 20:12  风雨后见彩虹  阅读(1640)  评论(0编辑  收藏  举报