PerfectVector
Автор: Irene Kim8 мин чтения

Текст SVG foreignObject: пропавшие подписи при экспорте

Исправьте подписи SVG, которые видны в браузере, но исчезают при экспорте. Сравните foreignObject с обычным текстом SVG, проверьте пространства имён и сохраните иллюстрацию.

На этой странице

Если фигуры SVG сохраняются при экспорте, а подписи исчезают, проверьте, использует ли пропавшая подпись <foreignObject>. В нём может находиться HTML, который браузер успешно размещает, но целевой рендерер не поддерживает. Замените проблемную подпись обычными элементами SVG <text> и <tspan> либо выберите способ экспорта, сохраняющий её внешний вид.

Сначала откройте в браузере именно экспортированный файл. Если подписи нет и там, проверьте её пространство имён, границы и стили, прежде чем обвинять импорт. Сохраните исходную иллюстрацию: трассировать всё изображение незачем, если сломался только контейнер текста.

Почему картинка сохраняется, а подпись исчезает

SVG может сочетать обычные фигуры с содержимым другого пространства имён XML. Гора, нарисованная через <path>, и солнце через <circle> — собственные элементы SVG. Абзац внутри <foreignObject> может быть HTML со своими правилами переноса и размещения. Справочник MDN по foreignObject описывает это различие.

Поэтому расширение .svg не обещает, что все части используют одни и те же возможности отрисовки. Целевое приложение может нарисовать гору и солнце, но пропустить HTML-абзац. Изменение цвета текста или увеличение разрешения экспорта не добавит этому рендереру поддержку HTML.

Что вы видитеЧто проверить дальшеВероятное исправление
Фигуры видны в обоих случаях; подписи — только в браузереИспользует ли пропавшая подпись foreignObject?Заменить эту подпись или сменить способ экспорта
HTML-подписи нет и в браузереПространство имён XHTML, явные границы, видимость и стилиСначала исправить HTML-контейнер
Обычный текст SVG отображается другим шрифтом или с другой длиной строкиДоступность шрифта и выбранные положения строкРешить проблему шрифтов или перевести окончательный текст в контуры
Пропала большая часть рисункаОбласть просмотра, обрезка и структура документаВыполнить более общие проверки пустого SVG

Небольшая проверка: меняем только подпись

Мы сделали карточку SVG размером 480 × 240 с контуром, кругом и словами «Keep artwork and labels separate.». Первый файл использует HTML-подпись. Второй сохраняет те же фигуры и заменяет только подпись обычным текстом SVG с тремя явно заданными строками.

В браузерном просмотре обе подписи появились. Преобразование тех же файлов в PNG через sharp 0.34.4 с поставляемой вместе с ним librsvg 2.61.1 дало результат ниже: HTML-подпись исчезла, а обычная SVG-подпись сохранилась. Вывод с HTML-подписью также попиксельно совпал с контрольным файлом, где подпись удалена. Это проверка этих файлов и этой версии рендерера, а не заключение о совместимости всех редакторов.

Четыре изображения одной иллюстрированной карточки: обе подписи видны в браузере, а librsvg пропускает HTML-подпись и сохраняет обычный текст SVG
Иллюстрация не меняется во всех четырёх случаях. Только HTML-подпись исчезает в выводе librsvg; обычный текст SVG использует явные переносы строк.

Исходный файл достаточно мал, чтобы воспроизвести его. Сохраните это как html-label.svg и откройте в браузере:

<svg xmlns="http://www.w3.org/2000/svg"
  width="480" height="240" viewBox="0 0 480 240">
  <rect width="480" height="240" rx="20" fill="#f5f1e7"/>
  <path d="M40 135Q90 15 140 135Z" fill="#087f75"/>
  <circle cx="90" cy="95" r="18" fill="#f4bc45"/>
  <foreignObject x="180" y="70" width="230" height="110">
    <div xmlns="http://www.w3.org/1999/xhtml"
      style="font: 28px/1.25 Arial, sans-serif; color: #172b34;">
      Keep artwork and labels separate
    </div>
  </foreignObject>
</svg>

Для второго файла замените весь элемент foreignObject следующей подписью и сохраните как native-label.svg:

<text x="180" y="96" font-family="Arial, sans-serif"
  font-size="28" fill="#172b34">
  <tspan x="180" dy="0">Keep artwork</tspan>
  <tspan x="180" dy="35">and labels</tspan>
  <tspan x="180" dy="35">separate</tspan>
</text>

Значение x начинает каждую строку в одном горизонтальном положении. Значения dy сдвигают последующие строки вниз. Здесь намеренно отказались от автоматического переноса HTML: автор выбирает разрывы строк и проверяет, что текст помещается. MDN описывает позиционирование tspan, а librsvg перечисляет поддерживаемые элементы SVG, включая text и tspan.

Откройте оба файла через реальный способ передачи — например, ваш конвертер изображений или генератор PDF. Сравнивайте сохранённый результат, а не только просмотр исходника. Совпадение размеров с примером не гарантирует совпадение шрифтов на другом компьютере.

Если подписи нет и в браузере

Проверяйте сохранённый файл .svg, а не только страницу, которая его создала. Встроенный SVG внутри HTML и отдельный документ SVG имеют разные контексты разбора.

Пример явно помещает div в http://www.w3.org/1999/xhtml. MDN отмечает, что это объявление пространства имён обязательно для HTML-содержимого в отдельном документе SVG, хотя встроенный HTML-пример может его опускать. Если вы создаёте элементы в JavaScript, используйте соответствующее пространство имён для дочернего HTML-элемента; div, созданный в пространстве имён SVG, не является контейнером HTML-абзаца.

Затем проверьте следующие части подписи:

  • Задайте для foreignObject явные положительные значения width и height, соответствующие нужной области подписи.
  • Разместите его координаты x и y внутри видимого рисунка, оставив место всем строкам.
  • Проверьте display, visibility, непрозрачность и цвет текста контейнера и его дочерних элементов.
  • Убедитесь, что экспортированный файл содержит нужные стили и не зависит от таблицы стилей окружающей веб-страницы.

В примере все стили подписи встроены, а блок имеет ширину 230 и высоту 110 единиц. Это исключает внешний CSS как переменную. Но не делает foreignObject совместимым с рендерером, у которого этой возможности нет.

Для экспорта draw.io преобразуйте подписи в исходнике

Если у вас сохранилась редактируемая схема, исправьте экспорт подписей в ней, прежде чем править XML вручную. Текущая документация draw.io об экспорте предлагает Convert Labels to SVG для поддерживаемых форматированных подписей: выберите фигуры или соединители, откройте раздел Advanced на вкладке Text и включите флажок.

У этой опции есть ограничения. Документация исключает из преобразования подписи со структурами вроде таблиц, списков, ссылок или фоновых цветов. Если опция недоступна, другой документированный путь — отключить Formatted Text и Word Wrap; возможно, потребуется вручную вставить переносы строк и заново проверить размещение.

Экспортируйте новую копию и откройте её в принимающем приложении. Скрытие предупреждения «Text is not SVG» не преобразует подпись. Встраивание шрифта решает зависимость от шрифта, но не отсутствие поддержки HTML-разметки.

В иллюстрированной схеме храните импортированную графику отдельно от подписей. Руководство по пользовательским фигурам SVG в draw.io разбирает графическую часть этого процесса.

Выберите формат текста с учётом получателя

Обычный текст SVG полезен, когда получателю нужно редактировать слова, но он всё ещё зависит от доступных шрифтов. Если подпись отображается другим шрифтом, выполните проверки шрифтов SVG, а не считайте это той же проблемой пропавшего контейнера.

Требование к передачеПрактический выборЧто проверить
Редактируемый текстОбычный text с продуманными положениями строкШрифт, длины строк и принимающий редактор
Фиксированная форма буквПеревести окончательный текст в контуры в исходном редактореПравильный вид; сохранить редактируемый оригинал
Сложная разметка только для браузераОставить foreignObject, если такой браузерный способ отвечает задачеРеальный встроенный или отдельный файл
Только внешний видЭкспортировать PNG рендерером, который показывает весь дизайнРазмеры в пикселях и самый мелкий текст при конечном размере

Перевод в контуры работает лишь тогда, когда исходный инструмент видит буквы и может преобразовать их. Открытие уже неполного экспорта и преобразование оставшихся объектов не восстановит слова, которых нет в импортированном документе. PNG сохраняет пиксели, поэтому не подходит, если получателю нужны редактируемые слова или векторные контуры резки.

Где PerfectVector пригодится для иллюстрированной карточки

Если иллюстрация карточки есть только в PNG или JPG, процесс преобразования клипарта в SVG в PerfectVector позволяет подготовить векторный вариант этой графики. Оставляйте слова отдельным текстовым элементом в редакторе дизайна. Проверьте края иллюстрации и внутренние промежутки, добавьте подпись и протестируйте собранный файл в целевом рендерере.

Руководство по векторизации изображений объясняет превращение пикселей в контуры. PerfectVector не исправляет HTML-подписи в SVG. Если у иллюстрации уже хорошие контуры, сохраните их и измените только проблемную подпись. Скриншот с пропавшей подписью не содержит букв для восстановления, а трассировка видимых букв создаст фигуры, а не редактируемые слова.

Перед отправкой исправленного SVG

  1. Заново откройте экспортированную копию в браузере и целевом приложении.
  2. Убедитесь, что видна каждая подпись, включая последнюю строку.
  3. Проверьте, что иллюстрация не сдвинулась и не изменила размер.
  4. Проверьте шрифты или просмотрите текст в контурах при нужном размере.
  5. Сохраните редактируемый исходник рядом с копией для передачи.

Частые вопросы

Почему текст SVG виден в Chrome, но исчезает при экспорте PNG? Подпись может быть HTML внутри foreignObject, тогда как PNG-рендерер поддерживает другой набор возможностей SVG. Проверьте разметку пропавшей подписи и проведите версию с обычным текстом SVG через тот же способ экспорта.

Добавление пространства имён XHTML исправляет любой экспорт foreignObject? Нет. Оно исправляет пространство имён HTML-содержимого в отдельном SVG. Целевое приложение всё ещё должно поддерживать это содержимое, а подписи нужны подходящие размеры и видимые стили.

Может ли tspan переносить текст как HTML-абзац? Пример использует явные строки и вертикальные смещения. Он не воспроизводит размещение HTML-абзаца. Выберите переносы под доступное пространство и проверьте их со шрифтом целевого приложения.

Стоит ли векторизовать всю карточку для восстановления подписей? Сохраните существующие контуры и заново создайте подпись из исходного текста. Векторизуйте только графику, существующую в пикселях. Трассированные буквы — это геометрия, поэтому редактируемые слова не сохраняются.

Источники

  1. MDN — foreignObject — Определяет содержимое другого пространства имён, геометрические атрибуты и пространство имён XHTML в отдельном SVG.
  2. MDN — tspan — Объясняет позиционирование частей обычного текста SVG.
  3. draw.io — Exported SVG text problems — Описывает преобразование в обычные SVG-подписи, ограничения форматирования и альтернативные настройки экспорта.
  4. GNOME — Librsvg supported SVG and CSS features — Перечисляет поддерживаемые рендерером элементы и атрибуты.

Если ваша иллюстрация всё ещё растровая, подготовьте клипарт в SVG, проверьте его фигуры и добавьте текст отдельно. Проверьте оба компонента в экспортированном файле перед передачей.

Ещё из блога

Начните с более чистого SVG,
который проще редактировать