Embed SVG in SVG?

六眼飞鱼酱① 提交于 2019-12-17 04:46:13

问题


I have an SVG document, and I would like to include an external svg image within it, i.e. something like:

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

("object" is just an example - the outer document will be SVG rather than xhtml).

Any ideas? Is this even possible? Or is the best thing for me to simply slap the logo.svg xml into my outer SVG document?


回答1:


Use the image element and reference your SVG file. For fun, save the following as recursion.svg:

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



回答2:


Or you can actually embed child svg in parent svg like this:

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

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




回答3:


It is worth mentioning that when you embed SVGs into another SVG with:

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

then the embedded SVG takes a rectangular shape with given dimensions.

That is to say, if your embedded SVG is a circle or some shape other than a square, then it becomes a square with transparency. Therefore, mouse events get trapped into that embeded square and do not reach the parent SVG. Watch out for that.

A better approach is using a pattern. To fill a shape, either a circle, a square or even a path.

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

Then use the pattern like this:

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

Now your mouse events do not get stuck into transparent image squares!




回答4:


I found that using the <image> tag gave a low-quality render of the embedded file. However the following technique worked (to embed an SVG file inside an SVG file - not necessarily for rendering on an HTML page):

  • Edit the SVG file in a text editor.

  • Find the end of the metadata:

    </metadata>
      <g
       id="layer1"
       inkscape:groupmode="layer"
       inkscape:label="Layer 1">
    
  • Insert this line after that group tag:

    <use xlink:href="OTHERFILE.svg#layer1" y="0" x="0" />
    
  • In this case we are including OTHERFILE.svg into the file, and all of layer1 (the first and default layer).

  • Save this and then open the file in Inkscape.

This technique is useful for having a standard background or logo on every page. By putting it first in the file it will be rendered first (and thus at the bottom). You could also lock it by adding this attribute:

sodipodi:insensitive="true" 

In other words:

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



回答5:


I needed to embed a SVG in my SVG but also change its color and apply transforms.

Only Firefox supports the "transform" attribute on the nested svg elements. Changing the color of <image> is also not possible. So a combination of both was needed.

What I ended up doing was the following

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

This works on at least Firefox, Chrome and Inkscape.

This behaves the same as the child svg in the parent svg answer with the exception that you can now apply transforms on it.




回答6:


Note xlink:href has been deprecated, just use href instead, e.g.

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

viewBox, width and height values (in this answer) are simply for illustration purpose, adjust the layout accordingly (read more).

Since <image> shares similar spec as <img>, meaning it doesn't support SVG styling, as mentioned in Christiaan's answer. For example, if I have the following css line that set the svg shape color to be the same as the font color,

svg {
  fill: currentColor;
}

The above style wouldn't apply if <image> is used. For that, you need to use <use>, as shown in Nick's answer.

Note id="layer1" and href="OTHERFILE.svg#layer1" values in his answer are mandatory.

Meaning you have to add the id attribute to the external svg file, so you need to host the (modified) external svg file by yourself (your website) or somewhere else. The resulting external svg file looks like this (notice where I put the id):

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

The value of id can be anything, I use "logo" in this example.

To embed that svg,

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

If you use the above svg as inline in your html, you don't need xmlns attribute (at least what I know from svgo).



来源:https://stackoverflow.com/questions/5451135/embed-svg-in-svg

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!