【问题标题】:How to use the <svg> viewBox attribute?如何使用 <svg> viewBox 属性?
【发布时间】:2013-02-26 11:20:30
【问题描述】:

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

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

【问题讨论】:

    标签: svg


    【解决方案1】:

    宽度和高度是&lt;svg&gt; 的大小。 viewBox 控制其内容的显示方式,因此 viewBox="0 0 1500 1000" 会将 &lt;svg&gt; 元素的内容缩小 5 倍(1500 / 300 = 5 和 1000 / 200 = 5),内容将是没有 viewBox 但 &lt;svg&gt; 的大小的 1/5

    假设您有一个弹性表面并将其切成 4 等份。如果你扔掉 3 块,你得到的表面是原始表面大小的 1/4。如果您现在拉伸曲面并使其与原始曲面大小相同,则曲面上的所有内容都将是两倍大小。这就是 viewBox 和宽度/高度的关系。

    【讨论】:

    • 缩小?如果没有 viewBox,图像将是 300px 宽,现在它必须被拉伸到 1500px 宽。我称之为放大,以指定大小的 5 倍显示内容。
    • 有多大 - 等等,如果不是绘制所有元素所需的区域,“ 大小”是多少?我的意思是,元素不是已经定义了吗? (抱歉,如果它变得 OT,但 宽度和高度及其元素之间的关系比 viewBox 本身更让我感到困惑。)
    • @AloisMahdal 请提出另一个问题,并提供有关您不了解的全部信息的完整信息。在 cmets 中来回并不理想。
    【解决方案2】:

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

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

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

    (由于 SVG 可缩放而不会损失分辨率,因此当用户放大或缩小时,像素在现实世界中的意义并不大。)

    它是一种坐标变换。

    我建议你从像“SVG Essentials”这样的书学习,大约使用了 10 美元,我从中粗略地引用了这个答案。

    【讨论】:

    • 我认为是 96dpi 而不是 90dpi。至少在 Inkscape 中,以防他们实现一些非标准的东西。
    【解决方案3】:

    默认

    <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/5 像素(1/5 缩小)。

    与原点相比,它们的高度也缩放到 1/5 像素(1/5 缩小)

    【讨论】:

    • 很好的解释。一直在阅读很多关于 svg 的内容,但都不清楚。您的回答帮助我理解了缩放,谢谢!
    【解决方案4】:

    主要:

    • viewBox 属性 与SVG 中的term viewport 密切相关

    缩写:

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

    默认值:

    • 单位 = 像素
    • 视口宽度 = 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 轴 50px 和沿 Y 轴 100px。

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

    • VP_width
    • VP_height

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

    • Vb_min_X
    • Vb_min_y

    SVG 图像可见部分的尺寸:

    • Vb_width
    • Vb_height

    渲染:
    在构造最终的 SVG 图像时,坐标系通过 COMBINING 进行变换:
    坐标系原点:

    • 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 分钟了解上述原理:
    video viewBox in SVG

    文档:
    W3C 2019 SVG 2 specification

    【讨论】:

      【解决方案5】:

      viewbox 是一个比率

      根据我的卑微经验,我一直认为 &lt;svg&gt;viewbox 值是必需的 image ratio 以应用于 widthheight 值。在定义后者时,我只对 DOM 中的任何 &lt;img&gt; 进行处理,无论是内联 HTML 属性还是通过 CSS,viewbox 属性仅适用于 SVG 文件。

      【讨论】:

        【解决方案6】:

        这里有一些实用信息,我认为这些信息有助于理解(尤其是使用)SVG viewPort 和 viewBox。

        SVG 使用 术语 viewPort 和 viewBox。 viewBox 位于 viewPort 内。 将 viewBox 视为图像本身——因为您可以缩放它,向左/向右/向上/向下滑动它——所有这些都在 viewPort 内。 viewPort(SVG 标签本身)就像一个容器,里面有 SVG 图像。你也可以调整它的大小,并左右移动它左/右/上/下。并且 SVG 标记位于 HTML 容器中(div、p、aside、h3 等)。所以你可以看到为什么人们会觉得 viewPort / viewBox 有点混乱。只需将 viewBox 视为图像本身。

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

        因此,在 SVG 本身上,您可以指定宽度 / 高度和起始 x 偏移量 / 起始 y 偏移量——这些称为 viewPort (又名 ViewPort 坐标系统) 在 viewBox 属性中,您指定“x y 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:视口的宽度/高度(在 SVG 标记本身上的宽度/高度,如 width="" 和 height="") 指定容器的大小将在其中显示 SVG 图像。通常,或者如果省略,它就是 SVG 图像本身的精确尺寸(或略大于)。

        超级重要的概念 #2:viewBox 的宽度/高度与 viewPort 的宽度/高度直接相关。 如果 viewPort 是 300 x 500 ,然后随着 viewBox W / H 数字变得大于 300 x 500,图像本身在 viewPort 内变得更小(缩小)。但是随着 viewBox w/h 变得小于 300 x 500,图像本身在 viewPort 内变得更大。这种增长是向右和向下的,所以如果你需要在现在太小的视口中滑动放大的图像,那就是当你使用 viewBox 的 X / Y 值时.

        viewBox x/y – 在视口内向右/向下滑动 SVG

        viewBox 宽度/高度——当增加大于 SVG 标记的宽度/高度时,它会在 viewPort 内将图像缩小。 SVG 在视口内向右/向下收缩。减少 SVG 宽度/高度属性下方的数字:图像将在视口中增长,直到右侧/底部的图像部分可能被视口的右侧/底部截断。 *(即当 viewBox 属性中的宽度/高度数字小于 SVG 上的宽度/高度属性时,图像会在 viewPort 内放大。当较大时,图像会随着 viewPort 缩小(缩小)。

        viewPort x/y == 在其 HTML 容器中向右/向下滑动视口本身 viewPort 宽度/高度 – 将整个 viewPort 的大小调整得更大,可能会溢出 HTML 容器(div / p / 等)。基本上,通过向右/向下增长来扩大视口。

        注意事项:
        一种。如果在 SVG 上不包含 ViewBox 属性,则 viewBox 的大小等于 viewPort 的大小(占 viewPort 的 100%)
        湾。如果 viewBox 以 0,0 开头并且宽度/高度与 SVG 宽度/高度(即视口)相同,则不会发生任何变化。相当于根本没有 viewbox 属性。
        C。如果您有一个纸牌大小的视口,但 SVG 图像是麦片盒的大小,那么增加 viewBox “xy ...”数字将在视口中向上/向左移动谷物盒图像,显示不同的麦片盒图像的一部分。这对sprites 很有用
        d。 (通常(总是!)SVG 元素也在 HTML 容器中 - 一个 div、p、section、li 等等。我们没有讨论这个,但请记住它。如果您的图像被截断,那么viewBox 比 viewPort 大 - 或者 - HTML 容器元素(div 等)比 viewPort 小)

        这是this answer within this same thread的作者推荐给我们的两个(非常棒!)短视频:

        2min video demo
        5min video demo (same guy, much better)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-03
          • 2018-09-05
          • 1970-01-01
          相关资源
          最近更新 更多