PerfectVector
Autor: Irene Kim9 min czytania

Tekst w elemencie foreignObject SVG: napraw brakujące etykiety po eksporcie

Napraw etykiety SVG, które pojawiają się w przeglądarce, ale znikają po eksporcie. Porównaj foreignObject z natywnym tekstem, sprawdź przestrzenie nazw i zachowaj istniejącą grafikę.

Na tej stronie

Jeśli kształty w SVG pozostają widoczne po eksporcie, ale etykiety znikają, sprawdź, czy brakująca etykieta używa <foreignObject>. Może on zawierać HTML, który przeglądarka poprawnie układa, ale którego docelowy mechanizm renderujący nie obsługuje. Zastąp problematyczną etykietę natywnymi elementami SVG <text> i <tspan> albo wybierz sposób eksportu, który zachowa jej wygląd.

Najpierw otwórz w przeglądarce dokładnie ten plik, który został wyeksportowany. Jeśli etykiety brakuje również tam, sprawdź jej przestrzeń nazw, granice obszaru i style, zanim uznasz, że winny jest importer. Zachowaj oryginalną grafikę: wektoryzacja całego obrazu jest zbędna, gdy zawiódł tylko kontener tekstu.

Dlaczego obraz pozostaje widoczny, a jego etykieta znika

SVG może łączyć zwykłe kształty z treścią z innej przestrzeni nazw XML. Góra narysowana za pomocą <path> i słońce narysowane za pomocą <circle> to natywne elementy SVG. Akapit wewnątrz <foreignObject> może być HTML-em, z własnymi regułami zawijania tekstu i układu. Dokumentacja foreignObject w MDN opisuje tę różnicę.

Rozszerzenie .svg nie gwarantuje więc, że każda część korzysta z tych samych funkcji renderowania. Docelowy mechanizm może narysować górę i słońce, pomijając akapit HTML. Zmiana koloru tekstu lub zwiększenie rozdzielczości eksportu nie doda temu mechanizmowi obsługi HTML.

Co widziszCo sprawdzić dalejPrawdopodobna naprawa
Kształty pojawiają się w obu miejscach; etykiety pojawiają się tylko w przeglądarceCzy brakująca etykieta używa foreignObject?Zastąp tę etykietę lub zmień sposób eksportu
Etykiety HTML brakuje również w przeglądarcePrzestrzeń nazw XHTML, jawnie określone granice obszaru, widoczność i styleNajpierw napraw kontener HTML
Natywny tekst pojawia się z innym krojem pisma lub inną długością wierszaDostępność fontów i wybrane pozycje wierszyRozwiąż problem z fontami lub zamień ostateczny tekst na krzywe
Brakuje większości rysunkuObszar widoku, przycinanie i struktura dokumentuSkorzystaj z szerszej listy kontroli dla pustego SVG

Mały test: zmień tylko etykietę

Przygotowaliśmy kartę SVG o wymiarach 480 × 240 ze ścieżką, kołem i napisem „Keep artwork and labels separate”. Pierwszy plik używa etykiety HTML. Drugi zachowuje te same kształty i zastępuje tylko etykietę natywnym tekstem w trzech jawnie określonych wierszach.

W naszym podglądzie w przeglądarce pojawiły się obie etykiety. Renderowanie tych samych plików do PNG za pomocą sharp 0.34.4, z dołączoną biblioteką librsvg 2.61.1, dało wynik pokazany poniżej: etykieta HTML zniknęła, a natywna etykieta pozostała. Wynik renderowania pliku z etykietą HTML był również identyczny piksel po pikselu z wynikiem dla pliku kontrolnego, z którego usunięto etykietę. To test tych plików i tej wersji mechanizmu renderującego, a nie ocena zgodności każdego edytora.

Cztery renderowania tej samej ilustrowanej karty: obie etykiety pojawiają się w przeglądarce, natomiast librsvg pomija etykietę HTML i zachowuje natywny tekst SVG
Grafika pozostaje niezmieniona we wszystkich czterech przypadkach. W wyniku renderowania przez librsvg znika tylko etykieta HTML; natywny tekst używa jawnych podziałów wierszy.

Oryginalny plik jest na tyle mały, że można go odtworzyć. Zapisz poniższy kod jako html-label.svg i otwórz go w przeglądarce:

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

W drugim pliku zastąp cały element foreignObject poniższą etykietą i zapisz plik jako 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>

Wartość x rozpoczyna każdy wiersz w tej samej pozycji poziomej. Wartości dy przesuwają kolejne wiersze w dół. To świadoma rezygnacja z automatycznego zawijania tekstu HTML: autor wybiera miejsca podziału wierszy i sprawdza, czy tekst się mieści. MDN opisuje pozycjonowanie tspan, a librsvg wymienia obsługiwane elementy SVG, w tym text i tspan.

Otwórz oba pliki w narzędziu, którego faktycznie używasz do przygotowania pliku dla odbiorcy, na przykład w konwerterze obrazów lub generatorze PDF. Porównaj zapisany wynik, a nie tylko podgląd źródła. Użycie wymiarów z przykładu nie gwarantuje takich samych fontów na innym komputerze.

Jeśli etykiety brakuje również w przeglądarce

Sprawdź zapisany plik .svg, a nie tylko stronę, która go utworzyła. SVG osadzone bezpośrednio w HTML i samodzielny dokument SVG są przetwarzane w różnych kontekstach składniowych.

W przykładzie element div jest jawnie umieszczony w przestrzeni nazw http://www.w3.org/1999/xhtml. MDN podaje, że ta deklaracja przestrzeni nazw jest wymagana dla treści HTML w samodzielnym dokumencie SVG, nawet jeśli można ją pominąć w przykładzie osadzonym bezpośrednio w HTML. Jeśli tworzysz elementy w JavaScript, użyj odpowiedniej przestrzeni nazw dla podrzędnego elementu HTML; div utworzony w przestrzeni nazw SVG nie jest kontenerem akapitu HTML.

Następnie sprawdź te części etykiety:

  • Nadaj foreignObject jawne, dodatnie wartości width i height odpowiadające planowanemu obszarowi etykiety.
  • Utrzymuj jego współrzędne x i y wewnątrz widocznego rysunku, pozostawiając miejsce na wszystkie wiersze.
  • Sprawdź display, visibility, krycie i kolor tekstu w kontenerze oraz jego elementach podrzędnych.
  • Upewnij się, że wyeksportowany plik zawiera potrzebne style, zamiast polegać na arkuszu stylów otaczającej go strony internetowej.

W przykładzie wszystkie style etykiety są zapisane bezpośrednio w elementach, a jej obszar ma szerokość 230 jednostek i wysokość 110 jednostek. Dzięki temu zewnętrzny CSS nie jest czynnikiem wpływającym na wynik testu. Nie sprawia jednak, że foreignObject będzie działać w mechanizmie renderującym, który nie obsługuje tej funkcji.

W eksportach z draw.io przekonwertuj etykiety w pliku źródłowym

Jeśli nadal masz edytowalny diagram, napraw w nim eksport etykiet, zanim zaczniesz ręcznie edytować XML. Aktualna dokumentacja eksportu draw.io udostępnia opcję Convert Labels to SVG (konwertuj etykiety na SVG) dla obsługiwanych etykiet z formatowaniem: zaznacz kształty lub łączniki, otwórz sekcję Advanced (zaawansowane) na karcie Text (tekst) i zaznacz pole wyboru.

Ta opcja ma ograniczenia. Dokumentacja wyklucza z tej konwersji etykiety zawierające takie struktury jak tabele, listy, linki lub kolory tła. Jeśli opcja jest niedostępna, innym opisanym w dokumentacji sposobem jest wyłączenie Formatted Text (tekst formatowany) i Word Wrap (zawijanie tekstu); może być konieczne ręczne wstawienie podziałów wierszy i ponowne sprawdzenie układu.

Wyeksportuj nową kopię i otwórz ją ponownie w aplikacji odbiorcy. Ukrycie ostrzeżenia „Text is not SVG” (tekst nie jest SVG) nie konwertuje etykiety. Osadzenie fontu rozwiązuje problem wynikający z zależności od tego fontu, a nie brak obsługi układu HTML.

W ilustrowanym diagramie zachowaj importowaną grafikę oddzielnie od etykiet. Poradnik tworzenia własnych kształtów SVG w draw.io omawia część tego procesu dotyczącą grafiki.

Wybierz format tekstu z myślą o kolejnej osobie

Natywny tekst jest przydatnym rozwiązaniem, gdy odbiorca musi edytować słowa, ale nadal wymaga dostępnych fontów, których można użyć. Jeśli etykieta pojawia się z niewłaściwym krojem pisma, skorzystaj z listy kontroli fontów SVG, zamiast traktować to jako ten sam problem z brakującym kontenerem.

Potrzeba odbiorcyPraktyczny wybórCo sprawdzić
Edytowalna treść tekstuNatywny text z celowo określonymi pozycjami wierszyFont, długości wierszy i edytor odbiorcy
Stałe kształty literZamień ostateczny tekst na krzywe w edytorze źródłowymPoprawny wygląd; zachowaj edytowalny plik główny
Rozbudowany układ przeznaczony wyłącznie do przeglądarkiZachowaj foreignObject, jeśli użycie tej przeglądarki spełnia wymaganiaFaktyczny plik osadzony lub samodzielny
Tylko wyglądWyeksportuj PNG z mechanizmu renderującego, który pokazuje cały projektWymiary w pikselach i najmniejszy tekst w rozmiarze przekazywanym odbiorcy

Zamiana na krzywe działa tylko wtedy, gdy narzędzie źródłowe widzi tekst i potrafi go przekonwertować. Otwarcie już niekompletnego eksportu i przekonwertowanie pozostałych obiektów nie przywróci słów, których brakuje w zaimportowanym dokumencie. PNG zachowuje piksele, więc nie nadaje się do sytuacji, w których odbiorca potrzebuje edytowalnych słów lub wektorowych ścieżek cięcia.

Gdzie PerfectVector przydaje się w ilustrowanej karcie

Jeśli ilustracja na karcie istnieje tylko jako PNG lub JPG, proces konwersji clipartu na SVG w PerfectVector pozwala przygotować jej wstępną wersję wektorową. Zachowaj treść etykiety jako oddzielny element tekstowy w edytorze projektu. Sprawdź krawędzie ilustracji i jej wewnętrzne prześwity, dodaj etykietę i przetestuj połączony plik w docelowym mechanizmie renderującym.

Poradnik wektoryzacji obrazów wyjaśnia, jak piksele stają się ścieżkami. PerfectVector nie naprawia etykiet HTML w SVG. Jeśli ilustracja ma już dobre ścieżki, zachowaj je i zmień tylko etykietę, która nie działa. Zrzut ekranu z brakującą etykietą nie zawiera liter, które można odzyskać, a wektoryzacja widocznych liter utworzyłaby kształty zamiast edytowalnych słów.

Zanim wyślesz naprawiony SVG

  1. Otwórz ponownie wyeksportowaną kopię w przeglądarce i docelowej aplikacji.
  2. Upewnij się, że każda etykieta jest widoczna, łącznie z jej ostatnim wierszem.
  3. Sprawdź, czy grafika nie przesunęła się ani nie zmieniła rozmiaru.
  4. Zweryfikuj fonty lub sprawdź tekst zamieniony na krzywe w docelowym rozmiarze.
  5. Zachowaj edytowalny plik źródłowy wraz z kopią dla odbiorcy.

Najczęściej zadawane pytania

Dlaczego tekst SVG jest widoczny w Chrome, ale znika po eksporcie do PNG? Etykieta może być HTML-em wewnątrz foreignObject, podczas gdy mechanizm renderujący PNG obsługuje tylko inny podzbiór funkcji SVG. Sprawdź kod brakującej etykiety i wyrenderuj wersję z natywnym tekstem, korzystając z tego samego sposobu eksportu.

Czy dodanie przestrzeni nazw XHTML naprawia każdy eksport foreignObject? Nie. Poprawia przestrzeń nazw treści HTML w samodzielnym SVG. Docelowy mechanizm nadal musi obsługiwać tę treść, a etykieta nadal wymaga odpowiednich wymiarów i stylów zapewniających widoczność.

Czy tspan może zawijać tekst jak akapit HTML? Przykład używa jawnie określonych wierszy i przesunięć pionowych. Nie odtwarza układu akapitu HTML. Wybierz miejsca podziału wierszy odpowiednie do dostępnej przestrzeni i sprawdź je z docelowym fontem.

Czy należy zwektoryzować całą kartę, aby odzyskać jej etykiety? Zachowaj istniejące ścieżki i odbuduj etykietę z jej oryginalnego tekstu. Wektoryzuj tylko grafikę, która istnieje jako piksele. Litery uzyskane przez wektoryzację są kształtami geometrycznymi, więc nie zachowują edytowalnych słów.

Źródła

  1. MDN — foreignObject — Definiuje treść z innej przestrzeni nazw, atrybuty geometrii i przestrzeń nazw XHTML w samodzielnym SVG.
  2. MDN — tspan — Wyjaśnia pozycjonowanie fragmentów natywnego tekstu SVG.
  3. draw.io — Exported SVG text problems — Opisuje konwersję na natywne etykiety, ograniczenia formatowania i alternatywne ustawienia eksportu.
  4. GNOME — Librsvg supported SVG and CSS features — Wymienia elementy i atrybuty obsługiwane przez mechanizm renderujący.

Jeśli Twoja ilustracja nadal jest obrazem rastrowym, przygotuj clipart jako SVG, sprawdź jego kształty i dodaj tekst oddzielnie. Zweryfikuj oba elementy w wyeksportowanym pliku, zanim przekażesz go odbiorcy.

Więcej z bloga

Zacznij od czystszego SVG,
który łatwiej edytować