如何使用<svg> viewBox属性?


73

我正在从官方文件中学习svg,有这样的说法。我不明白,如果它已经具有widthandheight属性,那么再次指定它又有viewBox="0 0 1500 1000"什么用呢?据说,“一个px单位被定义为等于一个用户单位。因此,“ 5px”的长度与官方文档中的“ 5”的长度相同,因此此viewBox的宽度为1500px, 1000高度视图,超过300px和200px。那么为什么要首先定义width和height值呢?

 <svg width="300px" height="200px" version="1.1"
         viewBox="0 0 1500 1000" preserveAspectRatio="none"
         xmlns="http://www.w3.org/2000/svg">

Answers:


88

宽度和高度是多少<svg>。viewBox控制其内容的显示方式,因此viewBox =“ 0 0 1500 1000”将按比例缩小<svg>元素(1500/300 = 5和1000/200 = 5),内容将为1 / 5没有viewBox时的大小,但是<svg>

假设您有一个弹性表面,并将其切成4个相等的部分。如果扔掉3块,则表面的大小是原始表面的1/4。如果现在拉伸表面并使其大小与原始表面相同,则该表面上的所有内容都会是该尺寸的两倍。这就是viewBox和width / height关联的方式。


1
缩小?没有viewBox,图像将为300px宽,现在必须将其拉伸为1500px宽。我称其为按比例放大,以指定大小的5倍显示内容。
Elise van Looij

<svg>有多大-等待,如果不是绘制所有元素所需的面积,“ <svg />大小”是多少?我的意思是,元素还没有定义吗?(很抱歉,如果它正在变旧,但是<svg />宽度和高度及其元素之间的关系比viewBox本身更使我感到困惑。)
Alois Mahdal

@AloisMahdal请询问另一个问题,其中提供您不了解的完整信息。在评论中来回不理想。
罗伯特·朗森

29

如果您未指定视图框,则假定元素中所有无单位的数字均为像素。(并且SVG假设将90 dpi或每英寸的像素从厘米等单位转换为像素。)

一个视图框使您可以在元素中使无单位数字表示“用户单位”,并指定如何将这些单位映射到大小。为简单起见,仅考虑x坐标,即标尺。您的视图框显示,标尺将具有1500个单位,以匹配svg的200像素大小的宽度。

从0到1500(无单位,即用户单位)的线元素在绘制时将拉伸200个像素,即横跨svg图形的宽度。

(并且由于SVG可伸缩且不会降低分辨率,因此当用户放大或缩小时,像素在现实世界中实际上并不意味着什么。)

它是一种坐标转换。

我建议您从类似“ SVG Essentials”的书中学习,大约要用10美元,我从中大致引用了这个答案。


我认为是96dpi而不是90dpi。至少在Inkscape中,如果它们实现了一些非标准的东西。
Genom

22

默认

<svg width="300" height="200">

svg网格的“标尺”以像素为单位(该svg中的所有形状均以像素为单位)

但是您想使用自己的单位,可以使用viewBox attr:

<svg width="300" height="200" viewBox="0 0 1500 1000">

这意味着:

横轴: 1500(您的宽度单位)= 300px => 1(您的宽度单位)= 300 / 1500px = 1 / 5px

垂直轴: 1000(您的身高单位)= 200px => 1(您的身高单位)= 200 / 1000px = 1 / 5px

  • 现在,svg中的所有形状都会缩放:

与原点相比,它们的宽度缩小到1 / 5px(缩小1/5 <1 =>)。

与原点相比,它们的高度也缩放为1 / 5px(1/5 <1 =>缩小)


1
很好的解释。已经读了很多关于svg的东西,但不清楚。您的回答帮助我了解了缩放比例,谢谢!
FraK

4

主要:

  • viewBox属性密切相关的术语视在SVG

缩写:

  • viewBox-VB
  • 视口-副总裁
  • 视口坐标系-VCS
  • 局部坐标系-LCS

句法:

<svg x = "VP_min_X" y = "VP_min_Y" width = "VP_width" height = "VP_height"
viewBox = "VB_min_X VB_min_Y VB_width VB_height">

默认值:

  • 单位= px
  • 视口宽度= 300
  • 视口宽度= 150
  • viewBox =视口

带有默认值的代码

<svg>

具有相同结果的代码:

<svg x = "0" y = "0" width = "300" height = "150" viewBox = "0 0 300 150">


视口设置:视口坐标系(VCS)的原始点:

  • VP_min_X
  • VP_min_Y

在最外面的视口中,这些值无关紧要,无论如何等于0,通常将它们省略:

<svg width = "100" height = "150">

结果相同的代码:(对于大多数外部视口):

<svg x = "10" y = 20 "width ="100 "height ="150">

嵌套
视口:在嵌套视口(VP_min_X,VP_min_Y)中,从VCS的原点定义缩进:

<svg width="100%" height="100%"> <!-- external viewport = full browser size -->
     <svg x="50" y="100" width="200" height="300" viewBox="0 0 100 100">
     </svg>
</svg>

在这种情况下,请缩进嵌套视口:
从外部VCS的起点到X轴分别为50像素和Y轴为100像素。

确定将在其中绘制SVG图形的矩形区域(视口)的尺寸:

  • VP_width
  • VP_height

视图框设置:
局部坐标系(LCS)的原点:

  • Vb_min_X
  • Vb_min_y

SVG图像可见部分的大小:

  • Vb_width
  • Vb_height

渲染:
构建最终的SVG图像时,坐标系统通过以下方式转换:
坐标系统的原点:

  • VCS(VP_min_X,VP_min_Y)
  • LCS(VB_min_X,VB_min_Y)

可见图像区域的端点:

  • VCS(VP_width,VP_height)
  • LCS(VB_width,VB_height)

能力:
结果,可以控制:

  • 视口在浏览器窗口中的位置[使用嵌套视口并进行更改(VP_min_X,VP_min_Y)]
  • 视口大小(VP_width,VP_height)
  • 平移图像的可见部分(使用viewBox并更改(VB_min_X,VB_min_Y))
  • 缩放图像的可见部分[使用viewBox并更改(VB_width,VB_height)]

可视化: 在YouTube上2分钟,以了解上述原理:
SVG中的视频viewBox

文档:
W3C 2019 SVG 2规范


0

viewbox 是一个比率

根据我的拙劣经验,我一直将<svg>viewbox值视为应用到和值所需的图像比率。在定义后期版本时,无论是内联HTML属性还是通过CSS,我都可以处理DOM中的任何内容,viewbox属性仅适用于SVG文件。widthheight<img>


0

这是一些实用的信息,对于理解SVG viewPort和viewBox(特别是与之配合使用)很有帮助。

SVG使用术语viewPort和viewBox。viewBox位于viewPort内部。将viewBox视为图像本身-因为您可以缩放它,因此可以在viewPort中全部向左/向右/向上/向下滑动。viewPort(SVG标签本身)就像是SVG图像位于其中的容器。您也可以调整大小,然后左右/左右移动。SVG标签位于HTML容器内(div,p,aside,h3等)。因此,您可以看到为什么人们发现viewPort / viewBox有点令人困惑。只需将viewBox视为图像本身即可。

SVG标签上的width / height属性提供了viewPort的大小。这是显示SVG图像的容器的宽度/高度。(您也可以x=""y=""属性,就像在viewBox属性中一样。)

因此,在SVG本身上,您指定width / height和起始x offset /起始y offset –称为viewPort (又名ViewPort Coord System) 。在viewBox属性中,指定“ xy width height” –这些称为viewBox (又称本地协调系统LCS)

<svg x="0" y="0" width="500" height="300"
  viewBox="start_x  start_y  width  height" >
  ...path fill d etc...
</svg>

重要概念1:viewPort的宽度/高度(在SVG标签自身上,为width =“”和height =“”)指定将显示SVG图像的容器的大小。通常,如果省略,则为SVG图片本身的确切大小(或稍大一点)。

超级重要概念2:viewBox的宽度/高度与viewPort的宽度/高度直接相关。如果viewPort为300 x 500,则当viewBox的W / H数大于300 x 500时,图像本身在viewPort中变小(缩小)。但是随着w / h的viewBox变得小于300 x 500,图像本身在viewPort中变得更大。这种增长是左右移动的,因此,如果您需要在现在太小的viewPort中滑动放大的图像,那就是使用viewBox的X / Y值时。

viewBox x / y –将SVG在viewPort内部向右/向下滑动

viewBox的宽度/高度–与SVG标签的宽度/高度相比,增大时,它会将图像缩小到viewPort内部。SVG在视口内向右/向下收缩。将数字减少到SVG宽度/高度属性以下:图像将在视口中增长,直到图像右侧/底部的部分可能被viewPort的右侧/底部截断。*(即,当viewBox属性中的宽度/高度数字小于SVG上的width / height属性时,viewPort中的图像ZOOMS IN。较大时,图像通过viewPort缩小(缩小)。

viewPort x / y ==在HTML容器的viewPort宽度/高度内向右/向下滑动视口–将整个viewPort调整为更大的尺寸,可能会使HTML容器溢出(div / p /等)。基本上,通过向右/向右增大viewPort使其更大。

注意事项:
一。如果未在SVG上包括ViewBox属性,则viewBox的大小等于viewPort的大小(占viewPort的100%)
b。如果viewBox开始0,0并且具有与SVG宽度/高度相同的宽度/高度(即viewPort),则什么都不会改变。等同于根本没有viewbox属性。
C。如果您的viewPort大小为一副纸牌,但SVG图像为谷物盒的大小,那么增加viewBox的“ xy…”数字将使谷物盒图像在viewPort中向上/向左移动,从而显示出不同的谷物盒图像的一部分。这对精灵
d很有用。(通常(总是(总是)!)SVG元素也位于HTML容器内-div,p,section,li等)。我们没有讨论过,但请记住。如果图像被截断,则可以使用viewBox大于viewPort-或者-HTML容器元素(div等)小于viewPort)

这是两个(出色的!)短片,由这个答案的作者在同一主题中提及:

2分钟的视频演示
5分钟的视频演示(同一个家伙,要好得多)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.