SVG图像的viewport和viewBox用于设置图像可见区域的大小。
SVG Viewportviewport是 SVG 图像的可见区域。一个SVG图像理论上可以无限大,但是在同一时刻只有图像的某些部分可以被看见。这个可见的区域就被称为viewport。
SVG viewport有点类似在浏览器中浏览一个页面。页面可以非常大,它的宽度要比浏览器的视口宽,高度也比浏览器的视口高度高,但是只有在当前屏幕中的页面是可见的区域,
你可以在 <svg> 元素中使用 width 和 height 属性来指定viewport的尺寸。
<svg width="500" height="300"></svg>
这个例子定义了一个500单位宽和300单位高的viewport。
在SVG中,只可以带单位,也可以不带单位。如果没有为值指定单位,那么它将使用像素为单位。也就是说上面的例子中,viewport的宽度为500像素,高度为300像素。
你也可以为这些值指定单位,在SVG中支持的长度单位有: em 、 ex 、 pt 、 px 、、 pc 、 cm 、 mm 、 in 和百分比值。
em:默认的字体大小,通常一个字符的高度
ex:字符 x 的高度
px:像素
pt:点数,1/72英寸
pc:Picas,1/6英寸
cm:厘米
mm:毫秒
in:英寸
在 <svg> 上设置的单位仅仅会作用在code><svg>元素上(viewport)。在SVG中的图形的尺寸有各个图形自己的单位决定。
下面是一个例子: <svg> 元素指定了 cm 单位,它里面的图形各自带有自己的单位。
<svg width="10cm" height="10cm"> <rect x="50" y="100" width="50" height="50" style="stroke: #000000; fill: none;"/> <rect x="100" y="100" width="50mm" height="50mm" style="stroke: #000000; fill: none;" /> </svg>
下面是返回结果,注意观察右边的图形要大于左边的图形。
SVG viewBox我们可以认为View Box是SVG“真正”的坐标系统。viewBox是用于在画布上绘制SVG图形的坐标系统。这个坐标系统可以比viewport大,也可以比viewport小,并且它可以在viewport中完全可见或部分可见。
如果你没有指定 viewBox 属性,那么浏览器会创建一个默认的用户坐标系统,这个用户坐标系统和viewport坐标系统相同。
你可以使用 viewBox 来指定自己的用户坐标系统。如果你指定的用户坐标系统和viewport坐标系统的宽高比相同,它将会被拉伸填充满整个viewport区域。如果宽高比不相同,你可以使用 preserveAspectRatio 属性来指定这个坐标系在viewport中是否完全可见,同时也可以指定它在viewport坐标系统中的位置。
viewBox的语法viewBox = <min-x> <min-y> <width> <height>
<min-x> 和 <min-y> 值决定viewbox的左上角位置。 <width> 和 <height> 值决定viewport的宽度和高度。注意viewBox的宽度和高度不需要设置得和 <svg> 元素的宽度和高度相同。<width>和<height>不允许设置为负数。
来看下面的例子:
<svg width="500" height="200" viewBox="0 0 50 20" > <rect x="20" y="10" width="10" height="5" style="stroke: #000000; fill:none;"/> </svg>
在这个例子中,viewBox从(0,0)开始,宽度为50像素,高度为20像素。这意味着,在500像素宽,200像素高的 <svg> 元素内部,使用从(0,0)开始,宽度为50像素,高度为20像素的坐标系统。换句话来说,图形的宽度中每一个单位对于 500/50=10像素的宽度。图形的高度中每一个单位对于 200/20=10像素的高度。这就是说,长方形的x坐标20,y坐标10实际上对应的是(200,100)坐标点,而它的宽度和高度分别为100像素和50像素。
下面是返回结果:
保持宽高比(preserveAspectRatio)如果viewport和viewBox的宽高比不相同。你需要自己来指定如何在SVG阅读器(如浏览器)中显示SVG图像。你可以在 <svg> 中使用 preserveAspectRatio 属性来指定。
preserveAspectRatio的语法preserveAspectRatio = defer? <align> <meetOrSlice>?
defer 参数是可选值,它仅仅在 image 元素上应用 preserveAspectRatio 属性时才使用。在使用其它元素时会被忽略。
align 参数是否强制进行均匀的缩放。如果 align 设置为 none ,图形会被缩放以适应viewport大小,而不会管它的宽高比。
其它的 preserveAspectRatio 值会在均匀缩放的同时保持viewbox的宽高比,并指定viewbox 在viewport中的对齐方式。 align 参数的值有分为两个部分,第一个部分指定X坐标的对齐方式,第二个部分指定Y坐标的对齐方式。下面列出了所以的X和Y对齐方式:
取值 描述 xMin viewBox的最小X值对齐viewport的左边部 xMid viewBox的X轴中点对齐viewport的X轴中点 xMax viewBox的最大X值对齐viewport的右边部 YMin viewBox的最小Y值对齐viewport的顶边 YMid viewBox的Y轴中点对齐viewport的Y轴中点 YMax viewBox的最大Y值对齐viewport的底边你可以将X对齐和Y对齐两两结合组成一个 align 参数,例如: xMaxYMax 或 xMidYMid 。
上面的这些取值时什么意思呢?一头雾水!你可以将它想象为CSS中使用百分比值时的 background-position 属性。 viewBox 就好像是背景图像,使用不同的 align 值就好比在viewport中使用不同的 background-position 值来定位 viewBox 一样。
看下面这张图,它的 align 取值为 xMidYMid 。图片中灰色坐标系是viewport的坐标系,蓝色的坐标系是viewBox的坐标系。当 align 取值为 xMidYMid 时,viewBox坐标系的中点和viewport坐标系的中点对齐。相当于CSS中的 backrgound-position: 50% 50%; 。
将上面表格中的各个值两两组合,可以得到下面的9种 align 值:
xMinYMin : viewBox 的 <min-x> 对齐viewport的最小X值, min-y 对齐viewport的最小Y值。相当于 backrgound-position: 0% 0%; 。
xMinYMid : viewBox 的 <min-x> 对齐viewport的最小X值, viewBox 的Y轴中点对齐viewport的Y轴中点。相当于 backrgound-position: 0% 50%; 。
xMinYMax : viewBox 的 <min-x> 对齐viewport的最小X值, min-y + <height> 对齐viewport的最大Y值。相当于 backrgound-position: 0% 100%; 。
xMidYMin : viewBox 的X轴中点对齐viewport的X轴中点, min-y 对齐viewport的最小Y值。相当于 backrgound-position: 50% 0%; 。
xMidYMid(默认值) : viewBox 的X轴中点对齐viewport的X轴中点, viewBox 的Y轴中点对齐viewport的Y轴中点。相当于 backrgound-position: 50% 50%; 。
xMidYMax : viewBox 的X轴中点对齐viewport的X轴中点, min-y + <height> 对齐viewport的最大Y值。相当于 backrgound-position: 50% 100%; 。
xMaxYMin : viewBox 的 <min-x> + <width> 对齐viewportX轴的最大值, min-y 对齐viewport的最小Y值。相当于 backrgound-position: 100% 0%; 。
xMaxYMid : viewBox 的 <min-x> + <width> 对齐viewportX轴的最大值, viewBox 的Y轴中点对齐viewport的Y轴中点。相当于 backrgound-position: 100% 50%; 。
xMaxYMax : viewBox 的 <min-x> + <width> 对齐viewportX轴的最大值, min-y + <height> 对齐viewport的最大Y值。相当于 backrgound-position: 100% 100%; 。
有些时候,根据 viewBox 的尺寸大小,上面的这些取值可能得到相同的结果。例如,当 viewBox="0 0 200 300" 的时候, align 分别取不同的值, meetOrSlice 的取值均为 meet ,得到下图的结果:
如果我们将 meetOrSlice 的取值设置为 slice ,将会得到不同的结果。如下图:
preserveAspectRatio 的另外一个参数 meetOrSlice 有三种取值:
取值 描述 meet 保持宽高比并将viewBox缩放为适合viewport的大小 slice 保持宽高比并将所有不在viewport中的viewBox剪裁掉 none 不保存宽高比。缩放图像适合整个viewbox,可能会发生图像变形看下面的图片,分别是 meet 和 slice 的情况。
可以看到,设置为 meet 时, viewBox 保持原来的宽高比,并且图像会全部显示。 meet 和CSS设置背景图像时的 background-siz:contain 是相同的。当设置为 slice 的时候, viewBox 保持原来的宽高比,同时放大到整个viewport的大小,超出viewport的部分被剪裁掉了。 slice 和CSS的 background-siz:cover 类似。
那么 viewBox 是根据什么来进行缩放的呢?
我们来看一个例子。这个例子中,viewport的宽度为500,高度为75。 viewBox 设置为 0 0 250 75 。这就意味着在x换走方向,每一个坐标单位代表2像素,在Y轴方向,每一个坐标单位代表1像素。因为在X轴方向的比例为500/250,在Y轴方向上的比例为75/75。这将会使图像发生扭曲,但是我们可以通过 preserveAspectRatio 来对它进行纠正。
第一个例子我们首先设置 preserveAspectRatio 为 xMinYMin meet 。这将确保宽高比保持不变, viewBox 会缩放以适应viewport的大小。 viewBox 根据宽高比中值较小的值来进行缩放。 也就是Y轴比例,它的值是1(X轴的比例是2)。 viewBox 将会被放置在viewport的左上角,因为 align 取值为 xMinYMin 。下面是代码和返回结果:
<svg width="500" height="75" viewBox="0 0 250 75" preserveAspectRatio="xMinYMin meet" style="border: 1px solid #cccccc;"> <rect x="1" y="1" width="50" height="50" style="stroke: #000000; fill:none;"/> </svg>
第二个例子我们将 preserveAspectRatio 设置为 xMinYMin slice 。这个设置同样保持宽高比,但是 viewbox 是根据宽高比中值较大的那个值来进行缩放 。也就是X轴的比例,它的值是2。它返回的图像要比viewport大,超出viewport的部分将会被剪裁掉。下面是代码和返回结果:
<svg width="500" height="75" viewBox="0 0 250 75" preserveAspectRatio="xMinYMin slice" style="border: 1px solid #cccccc;"> <rect x="1" y="1" width="50" height="50" style="stroke: #000000; fill:none;"/> </svg>
第三个例子我们将 preserveAspectRatio 设置为 none 。这意味着 viewBox 会填充整个viewport,意味X轴和Y轴的比例不相同,图像将会发生变形。
<svg width="500" height="75" viewBox="0 0 250 75" preserveAspectRatio="none" style="border: 1px solid #cccccc;"> <rect x="1" y="1" width="50" height="50" style="stroke: #000000; fill:none;"/> </svg>ViewBox的对齐方式
我们在来举一些 viewBox 对齐方式的例子。我们来看下面的代码:
<svg width="500" height="100" viewBox="0 0 50 50" preserveAspectRatio="xMinYMin meet" style="border: 1px solid #cccccc;"> <circle cx="25" cy="25" r="25" style="stroke: #000000; fill:none;"/> </svg>
这个例子中, svg 的宽度设置为500,高度设置为100, viewBox 设置为 0 0 50 50 。这意味着X轴方向上的比例为500/50=10,Y轴上的比例为100/50=2。在svg中的圆形半径为25,实际上它的宽高分别都是50个单位,填充满整个 viewBox (不是viewport)。
当我们指定它为 meet 时, viewBox 将根据Y轴来进行缩放,因为Y轴的比例较小。也就是说,在Y轴方向上 viewBox 将填充满viewport,但是在X轴方向上, viewBox 只会填充2 * 50像素=100像素。因为viewport有500像素的宽度,你必须要指定 viewBox 的水平对齐方式。这时 preserveAspectRatio 的 align 取值的第一部分可以是: xMin , xMid 或 xMax 。
下面是 preserveAspectRatio 取值分别为 xMinYMin meet , xMidYmin meet 和 xMaxYmin meet 是的返回结果。
与上面的例子相类似,如果 viewBox 的宽高比是在X方向上的值较小,而不是Y轴上,你就要指定Y轴上的对齐方式。
下面是一个例子,这里的viewport的宽设置为100,高设置为200。
viewBox 和上面的例子相同。这里Y轴的比例为200/50=4,X轴的比例为100/50=2。因为还是 meet 方式,这一次将根据X轴来进行缩放。在X轴方向上 viewBox 填满整个viewport,在Y轴方向上会填充2 * 50像素=100像素。
下面是 preserveAspectRatio 取值分别为 xMinYMin meet , xMinYMid meet 和 xMinYMax meet 是的返回结果。
返回SVG教程目录查看更多关于SVG基础 | SVG Viewport、View Box和preserveAspectRatio的详细内容...