30.SVG视口和视图框

SVG图片的视口和视图框设置了图片可见部分的尺寸。

视口

视口就是SVG图片的可视区域。SVG图像可以逻辑上与你想要的一样宽和高,但同一时间图像的某一部分是可见的。可见区域就被叫作视口。

你可以通过在<svg>元素上设置widthheight属性为其指定视口大小。示例如下:

<svg width="500" height="300"></svg>

这个例子定义了一个宽500单位高300单位的视口。

坐标系单位

如果你未在widthheight属性内指定任何单位,默认单位为像素。也就是说,宽度500表示500像素。

你也可以使用像素以外的单位。下面是你可以在<svg>元素上使用的单位的列表:

单位

描述

em

默认字体大小——通常是字符的高度

ex

字符x的高度

px

像素

pt

点(1/72英寸)

pc

皮卡(1/6英寸)

cm

厘米

mm

毫米

in

英寸

你在<svg>元素上设置的单位只会影响其(视口)的大小。SVG图像上显示的SVG形状的大小由你在每个形状上设置的单位确定。如果为指定单位,默认为像素。

下面这个例子展示了一个具有一组单位的<svg>元素,其中由包含一些具有自己的单位的形状:

<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>图片有一组单位为cm的属性。两个<rect>元素也有自己的单位集。一个使用像素(没有设置明确单位),另一个使用mm作为widthheight属性的单位。

最终图片如下,请注意,右侧框(widthheight单位为mm)比左侧框更大。

视图框

通过使用viewBox属性,你可以在<svg>元素中重新定义没有单位的坐标。示例如下:

<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>

此例创建了一个宽度为500像素,高度为200像素的<svg>元素。<svg>viewBox属性包含四个坐标。这些坐标定义了<svg>元素的视图框。坐标为视图框的x y width height

这个例子中,视图框从0,0开始,宽5020。这意味着,500x200像素的<svg>元素内部使用从0,050,20的坐标系。换句话说,<svg>内的图形上的坐标系每一个单位对应于宽度上的500/50=10像素和高度上的200/20=10像素。这就是为什么x位置为20,y位置为10的矩形真正位于200,100,并宽度(10)和高度(5)对应于100像素和50像素。

另一种解释方式是,viewBox属性的前两个坐标定义了<svg>元素的左上角的用户坐标,后两个坐标定义了右下角的用户坐标。<svg>内的空间被解释为从视图框左上坐标到右下坐标。

最终图片如下:

请注意,<rect>元素内的所有坐标都被解释为一个单位10像素。

保留宽高比

如果视口和视图框没有相同的纵横比(宽高比),你需要指定SVG查看器(例如浏览器)如何显示SVG图片。可以使用<svg>元素的preserveAspectRatio属性。

preserveAspectRatio属性采用由空格分割的两个值。第一个值告诉视图框如何在视口内对齐。这个值本身由两部分组成,第二个值(如果有的话)指示如何保留宽高比。

指定对齐的第一个值由两部分组成,第一部分指定x对齐,第二部分指定y对齐。下面是x和y对齐的值列表:

描述

xMin

将视图框的最小x与视口的左边缘对齐。

xMid

将视图x轴上的中点与x轴上的视口中心对齐。

xMax

将视图框的最大x与视口的右边缘对齐。

YMin

将视图框的最小y与视口的顶边对齐。

YMid

将视图y轴上的中点与y轴上的视口中心对齐。

YMax

将视图框的最大y与视口的底边对齐。

通过在x部分之后附加y部分,可以将x和y部分组合为单个值,这里有两个例子:

xMaxYMax
xMidYMid

这两个例子以不同的方式将视图框与视口对齐。第一个例子将视图框的右边缘与视口的右边缘对齐。第二个例子将视图框的中间对齐视口的中间。

preserveAspectRatio属性值的第二部分可以采用三个不同的值:

描述

meet

保留宽高比,并缩放视图框以适应视口。

slice

保留宽高比,并切割掉未适应在视口内的图像的任何部分。

none

不保留宽高比。缩放图像以使视图框完全适应视口,比例会被扭曲。

preserveAspectRatio属性值的第二部分附加到第一部分,并且以空格分隔。这里有两个例子:

preserveAspectRatio="xMidYMid meet"

preserveAspectRatio="xMinYMin slice"

我还没真正讨论过preserveAspectRatio各种设置的效果,所以让我们来看一下。

下面的例子都将width设置为500,height设置为75,viewBox属性设置为0 0 250 75。这意味着,x轴上的每个坐标单位对应于2像素,y轴上的每个坐标单位对应于1像素。如你所见,宽高比沿x轴为500/250=2,沿y轴为75/75=1。这可能导致图像失真,但我们将在下面的例子看到各种preserveAspectRatio设置如何工作的。

这里的第一个例子中preserveAspectRatio设置为xMinYMin meet。这将保留宽高比,并调整视图框的大小以适应视口。也就是说,根据两个宽高比中较小的一个(比例为1的y轴)缩放视图框。因为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。将保留宽高比,但是根据宽高比中较大的值(比例为2的x轴)缩放视图,这将导致图片太大以至于无法适应在视口内。图片被称为“切片”。

<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。这意味着视图框将填充整个视口,因为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>

视图框对齐

到目前为止,所有示例都是用了xMinYMin设置。根据你要如何在视口中对齐视图框,你可以使用不同的设置。我将更深入地讲解这些设置如何工作,但让我们先看一个例子:

<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>

这个例子使用了一个width为500height为100的<svg>元素。viewBox设置为0 0 50 50。最终,x轴上的比例为500/50=10,y轴上的比例为100/50=2。图片上的圆半径为25,使得它宽和高都为50个单位。因此,它填充整个视图框(而不是视口)。

当使用meet指示符时,视图框将根据y轴缩放,因为它具有较小的比例。这意味着,视图框将沿y轴(垂直)填充整个视口,但沿x轴(水平)仅填充250像素=100像素(比例视图框X维度)。由于视口宽度为500像素,因此你必须制定如何在视口内水平对齐视图框。可以使用preserveAspectRatio属性值第一部分的xMinxMidxMax部分。

下面三张图片展示了preserveAspectRatio属性值分别为xMinYMin meetxMidYMin meetxMaxYMin meet的效果。注意视图框如何根据设置对齐到左侧、中间和右侧。

同样的,如果图片x轴比例比y轴比例小,你必须指定其y对齐方式。

下面这个例子和上面的一样,但是现在的width为100,height为200。

视图框具有相同的尺寸,从而使得y轴的比例(200/50=4)大于x轴比例(100/50=2)。因此视图框将在x轴方向填满视口,而y轴方向不会。这使得必须指定视图框的y对齐方式。

<svg width="100" height="200" 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>

下面三张图片显示了y对齐分别为YMinYMidYMax

最后更新于