Nhúng SVG vào SVG?


98

Tôi có một tài liệu SVG và tôi muốn bao gồm một hình ảnh svg bên ngoài bên trong nó, tức là một cái gì đó như:

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

("object" chỉ là một ví dụ - tài liệu bên ngoài sẽ là SVG chứ không phải xhtml).

Bất kỳ ý tưởng? Điều này thậm chí có thể? Hay điều tốt nhất đối với tôi là chỉ cần gắn logo.svg xml vào tài liệu SVG bên ngoài của tôi?

Câu trả lời:


136

Sử dụng imagephần tử và tham chiếu tệp SVG của bạn. Để giải trí, hãy lưu những thứ sau thành 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
Cảm ơn, vì một số lý do mà googling của tôi cho điều này đã không hoạt động cho đến khi tôi đăng câu hỏi này. Tôi lưu ý rằng chiều rộng và chiều cao phải có để hình ảnh hiển thị.
Marcin

19
Một quan sát thú vị: các phiên bản mới nhất của Firefox, Chrome và Safari đều chỉ hiển thị một mức đệ quy (hai chấm) bằng cách sử dụng ở trên. Tuy nhiên, nếu bạn lưu ở trên với tên "a.svg" và thay đổi hình ảnh thành "b.svg", và sau đó cũng lưu nó thành "b.svg" với hình ảnh tham chiếu "a.svg", thì Firefox sẽ hiển thị thêm mức đệ quy cho mỗi lần bạn tải lại các tệp xen kẽ . Nó dường như kết quả bộ nhớ cache mỗi khi bạn tải tệp, đi sâu hơn một cấp.
Phrogz

6
@IanStormTaylor Một phần tử SVG không có thuộc tính kiểu; thay vào đó các mục bên trong phần tử SVG có kiểu dáng. Tuy nhiên, khi sử dụng <image>trong SVG (hoặc <img>hoặc <embed>trong HTML) để tham khảo một tập tin SVG bạn không được phép bước vào DOM bên dưới. Như vậy, không, bạn không thể tạo kiểu cho các phần tử bên trong một phần tử SVG đã được tham chiếu bởi một <image>.
Phrogz

2
@proteneer <image xlink:href="data:image/svg+xml;utf8,&lt;svg …&gt;… &lt;/svg&gt;" />. (Nếu bạn đang sử dụng JavaScript để đặt hrefthuộc tính, bạn không cần phải thoát khỏi các <ký tự v.v.)
Phrogz

1
xlink:hrefkhông được dùng nữa , bây giờ bạn chỉ nên sử dụng href. Bạn có thể cập nhật câu trả lời của mình để bao gồm điều đó không?
Vịt Donald

91

Hoặc bạn thực sự có thể nhúng svg con vào svg mẹ như thế này:

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

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


@toshi bạn có ví dụ khác về câu trả lời của mình không? tôi đang cố gắng nhưng không thực hiện được lời khuyên của bạn. SVG 'bên ngoài' của tôi đặt một vòng tròn và các gradient. SVG bên trong của tôi là một đối tượng. độc lập, SVG bên trong hoạt động như mong đợi. nhưng SVG bên trong không hiển thị khi tôi thực hiện lời khuyên của bạn. do đó, yêu cầu của tôi để xem một ví dụ khác.
Jay Grey

+1 để đề cập đến một giải pháp thay thế khép kín. Định vị / định cỡ của một svg nhúng như vậy hoạt động như thế nào?
bluenote10

40

Điều đáng nói là khi bạn nhúng SVG vào một SVG khác với:

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

thì SVG được nhúng có dạng hình chữ nhật với các kích thước đã cho.

Có nghĩa là, nếu SVG được nhúng của bạn là một hình tròn hoặc một số hình dạng khác với hình vuông, thì nó sẽ trở thành một hình vuông có độ trong suốt. Do đó, các sự kiện chuột bị mắc kẹt vào hình vuông được nhúng đó và không đến được SVG mẹ. Hãy coi chừng điều đó.

Một cách tiếp cận tốt hơn là sử dụng một mẫu. Để tô một hình dạng, hình tròn, hình vuông hoặc thậm chí là đường dẫn.

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

Sau đó, sử dụng mẫu như thế này:

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

Bây giờ các sự kiện chuột của bạn không bị mắc kẹt vào các hình vuông hình ảnh trong suốt!


Mẫu điền đó là hoàn hảo, cảm ơn bạn. Đối với các phần chèn nhỏ hơn hoặc các hộp xem nhỏ hơn, người viết mã có thể muốn giảm tất cả chiều rộng và chiều cao theo số đo bằng nhau.
Steve Taylor

7

Tôi nhận thấy rằng việc sử dụng <image>thẻ cho kết xuất tệp nhúng chất lượng thấp. Tuy nhiên, kỹ thuật sau đã hoạt động (để nhúng tệp SVG vào bên trong tệp SVG - không nhất thiết để hiển thị trên trang HTML):

  • Chỉnh sửa tệp SVG trong trình soạn thảo văn bản.

  • Tìm phần cuối của siêu dữ liệu:

    </metadata>
      <g
       id="layer1"
       inkscape:groupmode="layer"
       inkscape:label="Layer 1">
  • Chèn dòng này sau thẻ nhóm đó:

    <use xlink:href="OTHERFILE.svg#layer1" y="0" x="0" />
  • Trong trường hợp này, chúng tôi bao gồm OTHERFILE.svg vào tệp và tất cả lớp1 (lớp đầu tiên và lớp mặc định).

  • Lưu tệp này và sau đó mở tệp trong Inkscape.

Kỹ thuật này rất hữu ích để có nền hoặc biểu trưng chuẩn trên mọi trang. Bằng cách đặt nó đầu tiên trong tệp, nó sẽ được hiển thị đầu tiên (và do đó ở dưới cùng). Bạn cũng có thể khóa nó bằng cách thêm thuộc tính này:

sodipodi:insensitive="true" 

Nói cách khác:

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

@WilliamEntriken Bạn hiểu "tệp bên ngoài" là gì? Phương pháp tôi đã mô tả sử dụng tệp bên ngoài, cụ thể là tệp có nội dung khác trong đó.
Nick Gammon

5

Ghi chú xlink:hrefđã không được dùng nữa , chỉ cần sử dụng hrefthay thế, ví dụ:

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

viewBox, widthheightcác giá trị (trong câu trả lời này) chỉ nhằm mục đích minh họa, hãy điều chỉnh bố cục cho phù hợp ( đọc thêm ).

Kể từ khi <image> cổ phần đặc tả tương tự như <img>, có nghĩa là nó không hỗ trợ SVG phong cách, như đã đề cập trong câu trả lời của Christiaan . Ví dụ: nếu tôi có dòng css sau đặt màu svg shape giống với màu phông chữ,

svg {
  fill: currentColor;
}

Kiểu trên sẽ không áp dụng nếu <image>được sử dụng. Đối với điều đó, bạn cần phải sử dụng <use>, như được hiển thị trong câu trả lời của Nick .

Lưu ý id="layer1"href="OTHERFILE.svg#layer1"các giá trị trong câu trả lời của anh ấy là bắt buộc .

Có nghĩa là bạn phải thêm idthuộc tính vào tệp svg bên ngoài, vì vậy bạn cần lưu trữ tệp svg bên ngoài (đã sửa đổi) bởi chính bạn (trang web của bạn) hoặc ở một nơi khác. Tệp svg bên ngoài kết quả trông giống như thế này (lưu ý nơi tôi đặt id):

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

Giá trị của id có thể là bất kỳ thứ gì, tôi sử dụng "logo" trong ví dụ này.

Để nhúng svg đó,

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

Nếu bạn sử dụng svg ở trên làm nội tuyến trong html của mình, bạn không cần thuộc tính xmlns (ít nhất là những gì tôi biết từ svgo ).


1
viewBox là không bắt buộc, nếu bạn bỏ qua nó, bạn sẽ nhận được một bố cục khác, trong một số trường hợp, đó có thể là những gì bạn muốn. Safari chỉ mới bắt đầu hỗ trợ href.
Robert Longson

4

Tôi cần nhúng SVG vào SVG của mình nhưng cũng thay đổi màu sắc của nó và áp dụng các chuyển đổi.

Chỉ có Firefox hỗ trợ thuộc tính "biến đổi" trên các phần tử svg lồng nhau. Thay đổi màu sắc của <image> cũng không thể thực hiện được. Vì vậy, sự kết hợp của cả hai là cần thiết.

Những gì tôi đã làm là sau đây

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

Điều này hoạt động trên ít nhất Firefox, Chrome và Inkscape.

Điều này hoạt động giống như svg con trong câu trả lời svg cha, ngoại trừ trường hợp bạn có thể áp dụng các biến đổi trên đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.