ฝัง SVG ใน SVG?


102

ฉันมีเอกสาร SVG และฉันต้องการรวมภาพ svg ภายนอกไว้ในนั้นเช่น:

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

("object" เป็นเพียงตัวอย่าง - เอกสารภายนอกจะเป็น SVG แทนที่จะเป็น xhtml)

ความคิดใด ๆ ? เป็นไปได้หรือไม่? หรือเป็นสิ่งที่ดีที่สุดสำหรับฉันเพียงแค่ตบ logo.svg xml ลงในเอกสาร SVG ภายนอก

คำตอบ:


137

ใช้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
ขอบคุณสำหรับเหตุผลบางอย่าง googling ของฉันสำหรับสิ่งนี้ไม่ได้ผลจนกระทั่งฉันโพสต์คำถามนี้ ฉันทราบว่าต้องมีความกว้างและความสูงเพื่อแสดงภาพ
Marcin

20
ข้อสังเกตที่น่าสนใจประการหนึ่ง: Firefox, Chrome และ Safari เวอร์ชันล่าสุดทั้งหมดแสดงการเรียกซ้ำเพียงระดับเดียว (สองจุด) โดยใช้ด้านบน อย่างไรก็ตามหากคุณบันทึกด้านบนเป็น "a.svg" และเปลี่ยนรูปภาพเป็น "b.svg" จากนั้นบันทึกเป็น "b.svg" ด้วยรูปภาพที่อ้างอิง "a.svg" จากนั้น Firefox จะแสดงเพิ่มเติม ระดับการเรียกซ้ำในแต่ละครั้งที่คุณโหลดไฟล์สำรองใหม่ ดูเหมือนว่าจะแคชผลลัพธ์ทุกครั้งที่คุณโหลดไฟล์โดยจะลึกลงไปอีกหนึ่งระดับ
Phrogz

6
@IanStormTaylor องค์ประกอบ SVG ไม่มีคุณสมบัติสไตล์ตัวเอง แต่รายการที่อยู่ในองค์ประกอบ SVG จะมีสไตล์ แต่เมื่อใช้<image>ใน SVG (หรือ<img>หรือ<embed>ใน HTML) เพื่ออ้างอิงไฟล์ SVG คุณจะไม่ได้รับการเข้าถึง DOM พื้นฐาน ด้วยเหตุนี้คุณจึงไม่สามารถจัดรูปแบบองค์ประกอบภายในองค์ประกอบ SVG ที่อ้างอิงโดย<image>ไฟล์.
Phrogz

2
@proteneer <image xlink:href="data:image/svg+xml;utf8,&lt;svg …&gt;… &lt;/svg&gt;" />. (หากคุณใช้ JavaScript ในการตั้งค่าhrefแอตทริบิวต์คุณไม่จำเป็นต้อง<
เว้น

1
xlink:hrefจะเลิกhrefตอนนี้คุณก็ควรจะใช้ คุณช่วยอัปเดตคำตอบเพื่อรวมสิ่งนั้นได้ไหม
Donald Duck

93

หรือคุณสามารถฝัง 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 ภายในไม่แสดงในการดำเนินการตามคำแนะนำของคุณ ดังนั้นฉันขอดูตัวอย่างอื่น
Jay Grey

+1 สำหรับการกล่าวถึงทางเลือกในตัวเอง การวางตำแหน่ง / ขนาดของ svg ฝังตัวนั้นทำงานอย่างไร?
bluenote10

41

เป็นมูลค่าการกล่าวขวัญว่าเมื่อคุณฝัง 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>

ตอนนี้เหตุการณ์เมาส์ของคุณไม่ติดอยู่ในสี่เหลี่ยมภาพโปร่งใส!


รูปแบบการเติมนั้นสมบูรณ์แบบขอบคุณ สำหรับเม็ดมีดขนาดเล็กหรือช่องมองภาพขนาดเล็กผู้เขียนโค้ดอาจต้องการลดความกว้างและความสูงทั้งหมดในขนาดที่เท่ากัน
Steve Taylor

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 ไว้ในไฟล์และเลเยอร์ 1 ทั้งหมด (เลเยอร์แรกและเริ่มต้น)

  • บันทึกสิ่งนี้แล้วเปิดไฟล์ใน Inkscape

เทคนิคนี้มีประโยชน์สำหรับการมีพื้นหลังหรือโลโก้มาตรฐานในทุกหน้า โดยการใส่ไว้ก่อนในไฟล์ไฟล์นั้นจะแสดงผลก่อน (และอยู่ด้านล่างสุด) คุณยังสามารถล็อกได้โดยเพิ่มแอตทริบิวต์นี้:

sodipodi:insensitive="true" 

กล่าวอีกนัยหนึ่ง:

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

@WilliamEntriken "ไฟล์ภายนอก" หมายความว่าอย่างไร วิธีการที่ฉันอธิบายใช้ไฟล์ภายนอกคือไฟล์ที่มีสิ่งอื่นอยู่ในนั้น
Nick Gammon

6

หมายเหตุxlink:hrefได้รับการเลิกใช้เพียงแค่ใช้hrefแทนเช่น

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

viewBox, widthและheightค่า (ในคำตอบนี้) เป็นเพียงเพื่อวัตถุประสงค์ภาพประกอบปรับการจัดวางตาม ( อ่านรายละเอียดเพิ่มเติม )

เนื่องจาก<image> หุ้นสเปคที่คล้ายกันเป็น<img>ความหมายมันไม่สนับสนุนการจัดแต่งทรงผม SVG เป็นที่กล่าวถึงในคำตอบของ Christiaan ตัวอย่างเช่นหากฉันมีบรรทัด 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อาจเป็นอะไรก็ได้ฉันใช้ "โลโก้" ในตัวอย่างนี้

ในการฝัง svg นั้น

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

หากคุณใช้ svg ข้างต้นเป็นแบบอินไลน์ใน html ของคุณคุณไม่จำเป็นต้องมีแอตทริบิวต์ xmlns (อย่างน้อยสิ่งที่ฉันรู้จากsvgo )


1
viewBox ไม่บังคับหากคุณละเว้นคุณจะได้รับเค้าโครงที่แตกต่างกันในบางกรณีอาจเป็นสิ่งที่คุณต้องการ Safari เพิ่งเริ่มรองรับ href
Robert Longson

4

ฉันต้องการฝัง SVG ใน SVG แต่ยังเปลี่ยนสีและใช้การแปลง

Firefox เท่านั้นที่รองรับแอตทริบิวต์ "transform" บนองค์ประกอบ svg ที่ซ้อนกัน ไม่สามารถเปลี่ยนสีของ <ภาพ> ได้เช่นกัน ดังนั้นจึงจำเป็นต้องใช้ทั้งสองอย่างร่วมกัน

สิ่งที่ฉันทำมีดังต่อไปนี้

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

สิ่งนี้ใช้ได้กับ Firefox, Chrome และ Inkscape เป็นอย่างน้อย

สิ่งนี้จะทำงานเหมือนกับ svg ลูกในคำตอบ svg พาเรนต์โดยมีข้อยกเว้นว่าตอนนี้คุณสามารถใช้การแปลงกับมันได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.