在SVG中嵌入SVG?


98

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

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

(“对象”仅是示例-外部文档将是SVG而不是xhtml)。

有任何想法吗?这有可能吗?还是对我来说,最好只是将logo.svg xml拍到我的外部SVG文档中?

Answers:


135

使用该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>

3
谢谢,由于某种原因,直到我发布了此问题后,我对此的谷歌搜索才起作用。我注意到,必须具有宽度和高度才能渲染图像。
Marcin

19
一个有趣的发现:使用以上内容,最新版本的Firefox,Chrome和Safari都仅显示一级递归(两个点)。但是,如果将以上内容另存为“ a.svg”并将图像更改为“ b.svg”,然后还将其另存为“ b.svg”,且图像引用了“ a.svg”,则Firefox将显示其他内容每次重新加载交替文件时的递归级别。每次加载文件时,它似乎都可以缓存结果,从而将结果深一层。
Phrogz'3

6
@IanStormTaylor SVG元素本身没有样式属性;例如,而是SVG元素中的项目具有样式。然而,当使用<image>在SVG(或<img><embed>HTML格式)来引用您无权访问底层DOM的SVG文件。因此,不能,您不能在引用的SVG元素内设置元素的样式<image>
Phrogz 2012年

2
@proteneer <image xlink:href="data:image/svg+xml;utf8,&lt;svg …&gt;… &lt;/svg&gt;" />。(如果您使用JavaScript设置href属性,则无需转义<等字符。)
Phrogz 2015年

1
xlink:href已弃用,现在应该使用href。您能否更新您的答案以包含该答案?
唐老鸭

90

或者您实际上可以将子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不会显示在我对您的建议的实施中。因此,我要求再看一个例子。
杰伊·格雷

40

值得一提的是,当您通过以下方式将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>

现在,您的鼠标事件不会陷入透明的图像方块中!


填充模式非常完美,谢谢。对于较小的插入物或较小的视图框,编码人员可能希望以相同的方式减小所有宽度和高度。
史蒂夫·泰勒

7

我发现使用<image>标记会降低嵌入文件的渲染质量。但是,以下技术有效(将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“外部文件”是什么意思?我描述的方法使用一个外部文件,即其中包含其他内容的文件。
Nick Gammon

4

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

只有Firefox在嵌套的svg元素上支持“ transform”属性。也不能更改<image>的颜色。因此,需要将两者结合起来。

我最终要做的是以下几点

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

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

该行为与父svg答案中的子svg相同,不同之处在于您现在可以对其应用转换。


4

注意xlink:href弃用,请href改用,例如

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

viewBoxwidthheight的值(在此答案)仅仅是用于说明的目的,相应地调整布局(更多)。

由于<image> 股类似规格<img>,这意味着它不支持SVG的造型,正如上文克里斯蒂安的答案。例如,如果我有以下css行将svg形状颜色设置为与字体颜色相同,

svg {
  fill: currentColor;
}

如果<image>使用上述样式,则将不适用。为此,您需要使用<use>,如Nick的答案所示。

他的回答中的注释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了解到)。


1
viewBox不是强制性的,如果省略它,您将获得不同的布局,在某些情况下这可能是您想要的。Safari才刚刚开始支持href。
罗伯特·朗森,
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.