SVG Viewport和ViewBox

SVG图像的视口(Viewport)和视图框(ViewBox)可设置图像可见部分的尺寸。

viewport和viewbox的区别

1、viewport 视口,相当于显示器屏幕。

2、viewbox 视区,相当于在屏幕上截取一小块,放大到整个屏幕,就是特写的效果。

3、preserveAspectRatio 指定viewbox与viewport的对齐方式和缩放方式。

视口(Viewport)

视口(Viewport)是SVG图像的可见区域。逻辑上,SVG图像可以像您想要的一样宽和高,但是一次只能看到图像的特定部分。可见区域称为视口(Viewport)。

您可以使用元素的width和height属性来指定视口(Viewport)的大小<svg>。这是一个示例:

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

本示例定义的视口(Viewport)为500单位宽和300单位高。

坐标系统单位

如果您在width和height 属性内未指定任何单位,则假定单位为像素。即,width500表示500像素。

如果您喜欢使用不同于像素的单位,则可以。以下是可以与<svg>元素一起使用的单位的列表:

单元描述
em默认字体大小-通常是字符的高度。
ex角色的身高 x
px像素
pt点(1/72英寸)
pcPicas(1/6英寸)
cm公分
mm毫米
in英制

您在<svg>元素上设置的单位仅影响<svg> 元素(视口(Viewport))的大小。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 的width和height。

这是生成的图像。请注意,右边的框(中的width和height 单位mm)比左边的框大。

视图框(ViewBox)

您可以重新定义<svg>元素内没有单位的坐标的含义。您可以使用viewBox属性来执行此操作。这是一个示例:

<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>
测试看看‹/›

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

在这种情况下,视图框(ViewBox)从处开始0,0并且50宽而20高。也就是说,500 x 200像素<svg>元素在内部使用从0,0 到的坐标系50,20。换句话说,用于内部形状的坐标中的每1个单位<svg>对应于宽度500/50 = 10像素,高度对应200/20 = 10像素。这就是为什么x位置为20,y位置为10的矩形真正位于的原因200,100,并且其宽度(10)和高度(5)分别对应于100个像素和50个像素。

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

运行后图像效果:

请注意,<rect>元素内部的所有坐标如何解释为1个单位的10个像素。

保持宽高比

如果视口(Viewport)和视图框(ViewBox)的纵横比(宽高比)不同,则需要指定SVG查看器(例如浏览器)如何显示SVG图像。您可以使用元素的preserveAspectRatio属性来执行此操作<svg<。

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

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

描述
最小将视图框(ViewBox)的最小x与视口(Viewport)的左边缘对齐。
xMid将视口(Viewport)框x轴上的中点与视口(Viewport)中心在x轴上对齐。
最大值将视图框(ViewBox)的最大x与视口(Viewport)的右边缘对齐。
Min敏将视框的最小y与视口(Viewport)的上边缘对齐。
YMid将视区y轴上的中点与y轴上视口(Viewport)的中心点对齐。
YMax将视图框(ViewBox)的最大y与视口(Viewport)的底部边缘对齐。

通过将y部件附加在x部件之后,可以将x部件和y部件组合为一个值。这是两个示例:

xMaxYMax

xMidYMid

这两个示例使视图框(ViewBox)与视口(Viewport)的对齐方式不同。第一个示例将视框的右边缘与视口(Viewport)的右边缘对齐。第二个示例将视框的中间与视口(Viewport)的中间对齐。

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

描述
meet保留宽高比并缩放视图框(ViewBox)以适合视口(Viewport)。
slice保留宽高比并切掉不适合视口(Viewport)内部的图像任何部分。
none不保留宽高比。缩放图像以使视图框(ViewBox)完全适合视口(Viewport)。比例会失真。

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。这样可以确保保持宽高比,并调整视图框(ViewBox)的大小以适合视口(Viewport)。即,根据两个纵横比(y轴的比例为1)中的较小者缩放视图框(ViewBox)。由于xMinYMin 零件的原因,视图框(ViewBox)将位于视口(Viewport)的左上角。这是代码和生成的图像:

<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。这样可以保留宽高比,但是会根据较大的宽高比(x轴的比例为2)缩放视图框(ViewBox),从而导致图像太大而无法容纳在视口(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)对齐

到目前为止显示的所有示例都使用了该xMinYMin设置。根据您要如何在视口(Viewport)中对齐视图框(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 width="500" height="100" viewBox="0 0 50 50"    
preserveAspectRatio="xMidYMin meet"    
style="border: 1px solid #cccccc;">    
<circle cx="25" cy="25" r="25"    
style="stroke: #000000; fill:none;"/>    
</svg>    
<svg width="500" height="100" viewBox="0 0 50 50"    
preserveAspectRatio="xMaxYMin meet"    
style="border: 1px solid #cccccc;">    
<circle cx="25" cy="25" r="25"    
style="stroke: #000000; fill:none;"/>    
</svg>
测试看看‹/›

这个示例中示出了一个<svg>与元件width 组500和height设置为100。viewBox设为 0 0 50 50。这将导致x轴长宽比为500/50 = 10,y轴长宽比为100/50 =2。图像中的圆的半径为25,使其宽50度宽,高50个单位。因此,它会填充整个视图框(ViewBox)(而不是视口(Viewport))。

使用说明meet符时,视图框(ViewBox)将根据y轴缩放,因为它的纵横比较小。这意味着,视图框(ViewBox)将沿y轴(垂直)填充整个视口(Viewport),但仅沿x轴(水平)填充2 * 50像素= 100像素(纵横比*视图框(ViewBox)X尺寸) 。由于视口(Viewport)的宽度为500像素,因此您必须指定如何在视口(Viewport)内水平对齐视图框(ViewBox)。这样做使用xMin, xMid并xMax在第一部分的子部分preserveAspectRatio 的属性值。

这里有三个图像表示使用上面的示例中xMinYMin meet,xMidYmin meet 和xMaxYmin meet在preserveAspectRatio属性。请注意,视框如何将其与左侧,中央和右侧对齐(取决于设置)。

同样,如果图像沿x轴的纵横比小于y轴,则必须指定其y对齐。

这是以前的示例,但现在具有width100和height200:

视图框(ViewBox)的大小相同,因此使沿y轴的长宽比(200/50 = 4)大于沿x轴的长宽比(100/50 = 2)。因此,视图框(ViewBox)将在x轴方向而非y轴方向填充视口(Viewport)。这使得必须为视图框(ViewBox)指定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;"></circle>
</svg>
<svg width="100" height="200" viewbox="0 0 50 50" preserveaspectratio="xMinYMid meet" style="border: 1px solid #cccccc;">
    <circle cx="25" cy="25" r="25" style="stroke: #000000; fill:none;"></circle>
</svg>
<svg width="100" height="200" viewbox="0 0 50 50" preserveaspectratio="xMinYMax meet" style="border: 1px solid #cccccc;">
    <circle cx="25" cy="25" r="25" style="stroke: #000000; fill:none;"></circle>
</svg>
测试看看‹/›

这是三张图片,每张图片都显示了使用子部分值的一种可能的y对齐YMin, YMid以及YMax: