SVG in SVG einbetten?


97

Ich habe ein SVG-Dokument und möchte ein externes SVG-Bild darin einfügen, z. B.:

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

("Objekt" ist nur ein Beispiel - das äußere Dokument ist SVG und nicht xhtml).

Irgendwelche Ideen? Ist das überhaupt möglich? Oder ist es für mich das Beste, einfach die Datei logo.svg xml in mein äußeres SVG-Dokument zu schreiben?

Antworten:


133

Verwenden Sie das imageElement und verweisen Sie auf Ihre SVG-Datei. Speichern Sie zum Spaß Folgendes wie folgt 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
Danke, aus irgendeinem Grund hat mein Googeln dafür erst funktioniert, nachdem ich diese Frage gestellt habe. Ich stelle fest, dass Breite und Höhe vorhanden sein müssen, damit das Bild gerendert werden kann.
Marcin

19
Eine interessante Beobachtung: Die neuesten Versionen von Firefox, Chrome und Safari zeigen alle nur eine Rekursionsstufe (zwei Punkte) unter Verwendung der oben genannten. Wenn Sie jedoch das oben Gesagte als "a.svg" speichern und das Bild in "b.svg" ändern und es dann auch als "b.svg" speichern, wobei das Bild auf "a.svg" verweist, wird Firefox zusätzlich angezeigt Rekursionsstufen für jedes Mal, wenn Sie die alternierenden Dateien neu laden . Es scheint das Ergebnis jedes Mal zwischenzuspeichern, wenn Sie die Datei laden, und geht eine Ebene tiefer.
Phrogz

6
@IanStormTaylor Ein SVG-Element hat selbst keine Stileigenschaften. Vielmehr haben die Elemente im SVG-Element einen Stil. Wenn Sie jedoch <image>in SVG (oder <img>oder <embed>in HTML) auf eine SVG-Datei verweisen, erhalten Sie keinen Zugriff auf das zugrunde liegende DOM. Nein, Sie können keine Elemente innerhalb eines SVG-Elements formatieren, auf das von verwiesen wurde <image>.
Phrogz

2
@ Proteneer <image xlink:href="data:image/svg+xml;utf8,&lt;svg …&gt;… &lt;/svg&gt;" />. (Wenn Sie JavaScript verwenden, um das hrefAttribut <
festzulegen

1
xlink:hrefist veraltet , jetzt sollten Sie nur verwenden href. Könnten Sie Ihre Antwort aktualisieren, um dies einzuschließen?
Donald Duck

89

Oder Sie können das untergeordnete SVG wie folgt in das übergeordnete SVG einbetten:

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

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


@toshi hast du noch ein beispiel für deine antwort? Ich versuche, aber Ihren Rat nicht umzusetzen. Mein 'äußeres' SVG setzt einen Kreis und Farbverläufe. Mein inneres SVG ist ein Objekt. Standalone funktioniert die innere SVG wie erwartet. Aber die innere SVG wird in meiner Umsetzung Ihres Ratschlags nicht angezeigt. daher meine Bitte, ein anderes Beispiel zu sehen.
Jay Gray

39

Es ist erwähnenswert, dass beim Einbetten von SVGs in eine andere SVG mit:

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

dann nimmt das eingebettete SVG eine rechteckige Form mit vorgegebenen Abmessungen an.

Das heißt, wenn Ihr eingebettetes SVG ein Kreis oder eine andere Form als ein Quadrat ist, wird es zu einem Quadrat mit Transparenz. Daher werden Mausereignisse in diesem eingebetteten Quadrat eingeschlossen und erreichen die übergeordnete SVG nicht. Achten Sie darauf.

Ein besserer Ansatz ist die Verwendung eines Musters. Um eine Form zu füllen, entweder einen Kreis, ein Quadrat oder sogar einen Pfad.

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

Verwenden Sie dann das Muster wie folgt:

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

Jetzt bleiben Ihre Mausereignisse nicht mehr in transparenten Bildquadraten hängen!


Das Füllmuster ist perfekt, danke. Bei kleineren Einsätzen oder kleineren Ansichtsfeldern möchten Codierer möglicherweise alle Breiten und Höhen gleichermaßen reduzieren.
Steve Taylor

7

Ich fand heraus, dass die Verwendung des <image>Tags ein Rendering der eingebetteten Datei von geringer Qualität ergab. Die folgende Technik hat jedoch funktioniert (um eine SVG-Datei in eine SVG-Datei einzubetten - nicht unbedingt zum Rendern auf einer HTML-Seite):

  • Bearbeiten Sie die SVG-Datei in einem Texteditor.

  • Finden Sie das Ende der Metadaten:

    </metadata>
      <g
       id="layer1"
       inkscape:groupmode="layer"
       inkscape:label="Layer 1">
  • Fügen Sie diese Zeile nach diesem Gruppen-Tag ein:

    <use xlink:href="OTHERFILE.svg#layer1" y="0" x="0" />
  • In diesem Fall fügen wir OTHERFILE.svg in die Datei ein und die gesamte Ebene1 (die erste und die Standardebene).

  • Speichern Sie diese und öffnen Sie die Datei in Inkscape.

Diese Technik ist nützlich, um auf jeder Seite einen Standardhintergrund oder ein Standardlogo zu haben. Wenn Sie es zuerst in die Datei einfügen, wird es zuerst (und damit unten) gerendert. Sie können es auch sperren, indem Sie dieses Attribut hinzufügen:

sodipodi:insensitive="true" 

Mit anderen Worten:

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

@WilliamEntriken Was meinst du mit "externen Dateien"? Die von mir beschriebene Methode verwendet eine externe Datei, nämlich die Datei mit den anderen darin enthaltenen Elementen.
Nick Gammon

4

Ich musste ein SVG in mein SVG einbetten, aber auch seine Farbe ändern und Transformationen anwenden.

Nur Firefox unterstützt das Attribut "transform" für die verschachtelten SVG-Elemente. Das Ändern der Farbe von <Bild> ist ebenfalls nicht möglich. Also wurde eine Kombination von beiden benötigt.

Am Ende habe ich Folgendes getan

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

Dies funktioniert mindestens unter Firefox, Chrome und Inkscape.

Dies verhält sich genauso wie das untergeordnete SVG in der übergeordneten SVG-Antwort, mit der Ausnahme, dass Sie jetzt Transformationen darauf anwenden können.


4

Hinweis xlink:hrefist veraltet , verwenden Sie hrefstattdessen stattdessen z

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

viewBox, widthUnd heightWerte (in dieser Antwort) sind nur für Illustrationszwecke, stellen Sie das Layout entsprechend ( mehr lesen ).

Da es <image> ähnliche Spezifikationen wie hat <img>, was bedeutet, dass es das SVG-Styling nicht unterstützt, wie in Christiaans Antwort erwähnt . Wenn ich zum Beispiel die folgende CSS-Zeile habe, in der die Farbe der SVG-Form der Schriftfarbe entspricht,

svg {
  fill: currentColor;
}

Der obige Stil würde nicht gelten, wenn er <image>verwendet wird. Dafür müssen Sie verwenden <use>, wie in Nicks Antwort gezeigt .

Anmerkung id="layer1"und href="OTHERFILE.svg#layer1"Werte in seiner Antwort sind obligatorisch .

Das heißt, Sie müssen das idAttribut zur externen SVG-Datei hinzufügen , sodass Sie die (geänderte) externe SVG-Datei selbst (auf Ihrer Website) oder an einer anderen Stelle hosten müssen. Die resultierende externe SVG-Datei sieht folgendermaßen aus (beachten Sie, wo ich die abgelegt habe id):

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

Der Wert von id kann beliebig sein, ich verwende in diesem Beispiel "logo".

Um dieses SVG einzubetten,

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

Wenn Sie das obige svg als Inline in Ihrem HTML verwenden, benötigen Sie kein xmlns-Attribut (zumindest was ich von svgo weiß ).


1
viewBox ist nicht obligatorisch. Wenn Sie es weglassen, erhalten Sie ein anderes Layout. In einigen Fällen ist dies jedoch möglicherweise das, was Sie möchten. Safari hat gerade erst begonnen, href zu unterstützen.
Robert Longson
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.