Вбудувати SVG у SVG?


98

У мене є документ SVG, і я хотів би включити до нього зовнішнє зображення svg, тобто щось на зразок:

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

("об'єкт" - це лише приклад - зовнішній документ буде SVG, а не xhtml).

Будь-які ідеї? Чи можливо це взагалі? Або для мене найкраще просто ляпнути logo.svg xml у свій зовнішній SVG-документ?

Відповіді:


136

Використовуйте 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 покаже додаткові рівні рекурсії при кожному перезавантаженні змінних файлів . Здається, результат кешується кожного разу, коли ви завантажуєте файл, переходячи на один рівень глибше.
Фрогц

6
@IanStormTaylor Елемент SVG сам по собі не має властивостей стилю; швидше елементи у елементі SVG мають стиль. Однак при використанні <image>в SVG (або <img>чи <embed>в HTML) , щоб вставити посилання на файл SVG ви не надано доступ до основної DOM. Ні, ви не можете стилізувати елементи всередині елемента SVG, на який посилається файл <image>.
Фрогц

2
@proteneer <image xlink:href="data:image/svg+xml;utf8,&lt;svg …&gt;… &lt;/svg&gt;" />. (Якщо ви використовуєте JavaScript для встановлення hrefатрибута, вам не потрібно уникати <символів тощо.)
Phrogz 02

1
xlink:hrefзастаріло , тепер вам слід просто використовувати href. Не могли б ви оновити свою відповідь, включивши це?
Дональд Дак,

91

Або ви можете фактично вбудувати дочірній 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 не відображається в моїй реалізації вашої поради. отже, моє прохання побачити інший приклад.
Джей Грей,

+1 за згадку про самостійну альтернативу. Як працює позиціонування / розмір такого вбудованого svg?
bluenote10

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 і весь рівень1 (перший і за замовчуванням шар).

  • Збережіть це, а потім відкрийте файл у Inkscape.

Цей прийом корисний, якщо на кожній сторінці є стандартний фон або логотип. Помістивши його першим у файл, він буде відтворений першим (і, отже, внизу). Ви також можете заблокувати його, додавши цей атрибут:

sodipodi:insensitive="true" 

Іншими словами:

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

@WilliamEntriken Що ви маєте на увазі під "зовнішніми файлами"? Метод, який я описав, використовує зовнішній файл, а саме файл з іншими матеріалами в ньому.
Нік Гаммон,

5

Примітка xlink:hrefбуло застарілим , просто використовувати hrefзамість цього, наприклад ,

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

viewBox, widthа heightзначення (у цій відповіді) служать просто для ілюстрації, відповідно відрегулюйте макет ( докладніше ).

Оскільки <image> акції аналогічної специфікації , як <img>, маючи в увазі , що не підтримує SVG стиль, як зазначено в відповіді Християном в . Наприклад, якщо у мене є такий рядок css, який задає колір форми svg таким же, як і колір шрифту,

svg {
  fill: currentColor;
}

Зазначений вище стиль не застосовуватиметься, якщо <image>використовується. Для цього вам потрібно використовувати <use>, як показано у відповіді Ніка .

Зверніть увагу 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.
Роберт Лонгсон,

4

Мені потрібно було вбудувати SVG у свій SVG, а також змінити його колір і застосувати перетворення.

Тільки Firefox підтримує атрибут "перетворення" на вкладених елементах 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, за винятком того, що тепер ви можете застосовувати до нього перетворення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.