【问题标题】:Embed SVG in SVG?在 SVG 中嵌入 SVG?
【发布时间】:2011-07-23 23:53:16
【问题描述】:

我有一个 SVG 文档,我想在其中包含一个外部 svg 图像,例如:

<object data="logo.svgz" width="100" height="100" x="200" y="400"/>

("object" 只是一个示例 - 外部文档将是 SVG 而不是 xhtml)。

有什么想法吗?这甚至可能吗?还是将 logo.svg xml 简单地添加到我的外部 SVG 文档中对我来说是最好的选择?

【问题讨论】:

    标签: xml svg embedding


    【解决方案1】:

    使用 image 元素并引用您的 SVG 文件。为了好玩,将以下内容另存为recursion.svg

    <svg width="100%" height="100%" viewBox="-100 -100 200 200" version="1.1"
         xmlns="http://www.w3.org/2000/svg">
      <circle cx="-50" cy="-50" r="30" style="fill:red" />
      <image x="10" y="20" width="80" height="80" href="recursion.svg" />
    </svg>
    

    【讨论】:

    • 谢谢,由于某种原因,我的谷歌搜索直到我发布这个问题后才起作用。我注意到要渲染的图像必须存在宽度和高度。
    • 一个有趣的观察:最新版本的 Firefox、Chrome 和 Safari 都只显示了使用上述方法的一级递归(两个点)。但是,如果您将上述内容另存为“a.svg”并将图像更改为“b.svg”,然后将其保存为“b.svg”并且图像引用“a.svg”,那么Firefox 将显示附加每次重新加载交替文件时的递归级别。每次加载文件时,它似乎都会缓存结果,更深一层。
    • @IanStormTaylor SVG 元素本身没有样式属性;而是 SVG 元素内的项目具有样式。但是,当使用 SVG 中的 &lt;image&gt;(或 HTML 中的 &lt;img&gt;&lt;embed&gt;)来引用 SVG 文件时,您无法访问底层 DOM。因此,不,您不能在被 &lt;image&gt; 引用的 SVG 元素中设置元素样式。
    • @proteneer &lt;image xlink:href="data:image/svg+xml;utf8,&amp;lt;svg …&amp;gt;… &amp;lt;/svg&amp;gt;" /&gt;。 (如果您使用 JavaScript 设置 href 属性,则无需转义 &lt; 等字符。)
    • xlink:href is deprecated,现在你应该只使用href。您能否更新您的答案以包含该内容?
    【解决方案2】:

    或者您实际上可以像这样将子 svg 嵌入父 svg:

    <svg>
        <g>
            <svg>
                ...
            </svg>
        </g>
    </svg>
    

    演示:
    http://hitokun-s.github.io/old/demo/path-between-two-svg.html

    【讨论】:

    • @toshi 你有另一个回答的例子吗?我正在尝试但未能实施您的建议。我的“外部”SVG 设置了一个圆圈和渐变。我的内部 SVG 是一个对象。独立,内部 SVG 按预期工作。但内部 SVG 不会显示在我对您建议的实施中。因此,我请求查看另一个示例。
    • +1 用于提及独立的替代方案。这种嵌入式 svg 的定位/大小如何工作?
    • 我想补充一点,你可以为这个 元素添加变换:平移、旋转等。这样你可以动态地重新定位元素
    • 例如,要移动一个元素,你可以这样写:...
    【解决方案3】:

    值得一提的是,当您将 SVG 嵌入到另一个 SVG 中时:

    <image x="10" y="20" width="80" height="80" xlink:href="image.svg" />
    

    然后嵌入的 SVG 采用具有给定尺寸的 矩形 形状。

    也就是说,如果您嵌入的 SVG 是圆形或正方形以外的其他形状,那么它就会变成具有透明度的正方形。因此,鼠标事件会被困在嵌入的正方形中,并且不会到达父 SVG。请注意这一点。

    更好的方法是使用模式。填充形状,可以是圆形、正方形,甚至是路径。

    <defs>
     <pattern id="pat" x="0" y="0" width="500" height="500" patternUnits="userSpaceOnUse">
       <image x="0" y="0" width="500" height="500" xlink:href="images/mysvg.svg"></image>
     </pattern>
    </defs>
    

    然后使用这样的模式:

    <circle cx="0" cy="0" r="250" fill="url(#pat)"></circle>
    

    现在您的鼠标事件不会卡在透明图像方块中了!

    【讨论】:

    • 那个填充图案很完美,谢谢。对于较小的插入或较小的视图框,编码人员可能希望以同等方式减小所有宽度和高度。
    【解决方案4】:

    我发现使用&lt;image&gt; 标签会导致嵌入文件的渲染质量很低。然而,以下技术有效(将 SVG 文件嵌入到 SVG 文件中 - 不一定用于在 HTML 页面上呈现):

    • 在文本编辑器中编辑 SVG 文件。

    • 找到元数据的结尾:

      </metadata>
        <g
         id="layer1"
         inkscape:groupmode="layer"
         inkscape:label="Layer 1">
      
    • 在该组标签之后插入这一行:

      <use xlink:href="OTHERFILE.svg#layer1" y="0" x="0" />
      
    • 在这种情况下,我们将 OTHERFILE.svg 包含到文件中,以及 layer1 的所有内容(第一层和默认层)。

    • 保存此文件,然后在 Inkscape 中打开文件。

    此技术对于在每个页面上都有标准背景或徽标很有用。通过将它放在文件中,它将首先呈现(因此在底部)。你也可以通过添加这个属性来锁定它:

    sodipodi:insensitive="true" 
    

    换句话说:

    <use xlink:href="OTHERFILE.svg#layer1" sodipodi:insensitive="true" y="0" x="0" />
    

    【讨论】:

    • @WilliamEntriken “外部文件”是什么意思?我描述的方法使用了一个外部文件,即包含其他内容的文件。
    【解决方案5】:

    注意xlink:href 一直是deprecated,只需使用href 代替,例如

    <svg viewBox="0 0 512 512">
      <image width="512" height="512" href="external.svg"/>
    </svg>
    

    viewBoxwidthheight 值(在此答案中)仅用于说明目的,请相应调整布局 (read more)。

    由于&lt;image&gt; shares similar spec&lt;img&gt;,这意味着它不支持SVG 样式,如Christiaan's answer 中所述。例如,如果我有以下 css 行将 svg 形状颜色设置为与字体颜色相同,

    svg {
      fill: currentColor;
    }
    

    如果使用&lt;image&gt;,上述样式将不适用。为此,您需要使用&lt;use&gt;,如Nick's answer所示。

    注意他回答中的id="layer1"href="OTHERFILE.svg#layer1" 值是强制

    意味着您必须将 id 属性添加到外部 svg 文件中,因此您需要自己(您的网站)或其他地方托管(修改后的)外部 svg 文件。生成的外部 svg 文件如下所示(注意我把 id 放在哪里):

    <svg id="logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
      <path d="..."/>
    </svg>
    

    id的值可以是任何值,我在这个例子中使用了“logo”。

    要嵌入该 svg,

    <svg viewBox="0 0 512 512">
      <use href="edited-external.svg#logo"/>
    </svg>
    

    如果您在 html 中使用上述 svg 作为内联,则不需要 xmlns 属性(至少我从 svgo 知道的)。

    【讨论】:

    • viewBox 不是强制性的,如果您省略它,您将获得不同的布局,但在某些情况下这可能是您想要的。 Safari 才刚刚开始支持 href。
    【解决方案6】:

    我需要在我的 SVG 中嵌入一个 SVG,但还需要更改它的颜色并应用变换。

    只有 Firefox 支持嵌套 svg 元素的“transform”属性。也无法更改 的颜色。因此需要将两者结合起来。

    我最终做的是以下

    <svg>
      <image x="0" y="0" xlink:href="data:image/svg+xml;base64,[base64 of nested svg]"></image>
    </svg>
    

    这至少适用于 Firefox、Chrome 和 Inkscape。

    这与父 svg 答案中的子 svg 的行为相同,但您现在可以对其应用转换。

    【讨论】:

      【解决方案7】:

      使用 SVG &lt;use&gt; 标签嵌入额外的 SVG 怎么样?

      【讨论】:

        【解决方案8】:

        非常简单

        <image x="120" y="720" width="1000" height="900" href="assets/img/image.svg" />
        

        【讨论】:

          猜你喜欢
          • 2011-12-23
          • 2022-11-20
          • 2010-12-09
          • 1970-01-01
          • 2021-06-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-11
          相关资源
          最近更新 更多