Jak wyświetlić plik SVG w React Native?


111

Chcę pokazać pliki SVG (mam kilka obrazów SVG), ale coś, czego nie mogłem znaleźć sposobu na pokazanie. Próbowałem użyć komponentów Image i Use z React-native-svg, ale nie działają z tym. Próbowałem to zrobić w natywny sposób, ale pokazanie tylko obrazu svg jest naprawdę ciężką pracą.

Przykładowy kod:

import Svg, {
  Use,
  Image,
} from 'react-native-svg';

<View>
  <Svg width="80" height="80">
     <Image href={require('./svg/1f604.svg')} />
  </SvgRn>
</View>

Wiem też, że React Native nie obsługuje w zasadzie svg, ale myślę, że ktoś naprawił ten problem w trudny sposób (z / bez React-native-SVG)


Nie możesz użyć do wyświetlenia całego pliku, potrzebujesz do tego obrazu.
— Robert Longson

Tak, próbowałem też @RobertLongson, ale to też nie działa.
— the_bluescreen

Możesz dodać to jako css backgroundImage, czy próbowałeś tego?
— danielarend

Próbowałem, ale komponent React Native View nie obsługuje właściwości backgroundImage w stylu css. @danielarend
— the_bluescreen

Nie jestem pewien, dlaczego miałbyś użyć opakowania SVG do zawijania obrazu SVG.
— Robert Longson

Odpowiedzi:


75

Użyłem następującego rozwiązania:

  1. Konwertuj .svgobraz na JSX za pomocą https://svg2jsx.herokuapp.com/
  2. Konwertuj JSX na react-native-svgkomponent za pomocą https://svgr.now.sh/ (zaznacz pole wyboru „React Native)

Jak więc używać tego komponentu? Czy możesz udostępnić kod?
— Indranil Dutta

Jeśli klikniesz ten link, zobaczysz przykład z importem svgr.now.sh (zaznacz pole wyboru „React Native). Użyj go jako zwykłego komponentu Reacta, zamiast <Image src = {...} /> i powinno działać
— Ihor Burlachenko

1
@IhorBurlachenko Kiedy znudziłem twoje rozwiązanie, otrzymałem ten błąd Uncaught Error: Niezmienione naruszenie: Typ elementu jest nieprawidłowy: oczekiwano ciągu (dla wbudowanych komponentów) lub klasy / funkcji, ale otrzymałem: obiekt . czy możesz mi tu pomóc?
— Potężny

2
Każdy, kto ma problem z użyciem tego podejścia, upewnij się, że instalujesz najnowszą wersję react-native-svgpakietu. Upewnij się również, że uruchomiłeś to polecenie, aby połączyć swój pakietreact-native link react-native-svg
— connect2Coder

2
To długi proces implementacji plików SVG, lepiej korzystaj z github.com/kristerkari/react-native-svg-transformer, jak zasugerowano poniżej stackoverflow.com/a/55604442/1854104
— hefgi

10

Opublikowałem tutaj inne rozwiązanie, które jest najlepszym podejściem do wstawienia wykresu wektorowego (svg) do natywnej aplikacji reagującej. To podejście wykorzystuje czcionkę wektorową (z svg) zamiast pliku svg. PS: Działa świetnie na iOS i Android, a także możesz zmienić kolor i rozmiar ikony wektora.

Jeśli chcesz wstawić plik SVG bezpośrednio do swojej aplikacji, możesz wypróbować bibliotekę innej firmy: React-native-svg. Z ponad 3 tysiącami gwiazdek na githubie jest to jedno z najlepszych rozwiązań.

  • zainstalować:
    • npm reaguję-native-svg
    • npm reaguję-native-svg-uri
  • połącz z natywnym:
    • łącze react-natywne reaguj-natywne-svg

A oto próbka:

import * as React from 'react';
import SvgUri from 'react-native-svg-uri';
import testSvg from './test.svg';
export default () => (
  <SvgUri
    width="200"
    height="200"
    svgXmlData={testSvg}
  />
);

Daje błąd „nie można dodać dziecka, które nie ma węzła css do węzła bez funkcji miary”.
— Pulkit Aggarwal

Użyłem ostatniego z source = {require ('myImagePath')}, ale daje mi błąd.
— Pulkit Aggarwal

1
Spójrz na odpowiedź, którą tutaj zamieszczam, używając czcionki zamiast svg. to lepsze rozwiązanie: stackoverflow.com/questions/49951885/ ...
— Cassio Seffrin

2
Ta biblioteka działa tak wolno. Otacza każdy plik SVG we własnym widoku internetowym.
— JP_

1
tnx, to było najszybsze rozwiązanie, ale zamiast svgXmlData = {testSvg} użyłem source = {testSvg} działało jak urok. tnx ponownie.
— Andris Laduzans

9

Po wypróbowaniu wielu sposobów i bibliotek zdecydowałem się stworzyć nową czcionkę (z Glifami lub tym samouczkiem ) i dodać do niej moje pliki SVG, a następnie użyć komponentu "Tekst" z moją niestandardową czcionką.

Mam nadzieję, że pomoże to każdemu, kto ma ten sam problem z SVG w natywnym reagowaniu.


Myślę, że masz rację, rodzina czcionek to chyba najprostszy sposób na uzyskanie prostych pomostów żylnych w reagują rodzimy
— Joe Lloyd

Niezły tutorial na ten temat: blog.bam.tech/developper-news/… . Wymaga pakietu Vector Icons Node.
— Rafa,

To rozwiązanie nie jest poprawne, jeśli musisz zaimportować wielokolorowy plik zwisu
— Joe Aspara

Wypróbowałem jego rozwiązanie z icomoon i nie wyszło, ani ich wsparcie nie jest aktywne. Fontello zmienia moje pliki SVG.
— Siraj Alam,

6

Zainstaluj React-native-svg-transformer

npm reaguję-native-svg-transformer --save-dev

Używam SVG w następujący sposób i działa dobrze

import LOGOSVG from "assets/svg/logo.svg"

w renderowaniu

<View>
  <LOGOSVG 
    width="100%"
    height="70%"
  />
</View>

Kiedy importuję plik SVG HEARTSVG z folderu obrazu, to pokazuje błąd. I bez błędu importowania plików png. Jakieś sugestie?
— Rakesh

4

Miałem ten sam problem. Używam tego rozwiązania, które znalazłem: React Native wyświetla SVG z pliku

To nie jest idealne i wracam dzisiaj, ponieważ działa o wiele gorzej na Androidzie.


Właściwie to kreatywna odpowiedź, ale nie pomaga w moich dopasowaniach :) Ponieważ użyję listy ikon (10 lub więcej ikon SVG), więc jeśli tego użyję, może to być naprawdę złe dla wydajności. Co myślisz?
— the_bluescreen

Wyrenderowałem 10-15 svg na stronie. Nikt nie narzekał na iOS, wszyscy narzekali na Androida. W iOS występuje opóźnienie 0,1-0,3 sekundy (ułamek sekundy błysk bieli przed załadowaniem). Na Androidzie może to trwać 1 sekundę, a czasami nigdy się nie ładują. W końcu sprawdziłem swoje pliki SVG, a następnie napisałem skrypt, który konwertuje je na pliki PNG o dokładnie odpowiednim rozmiarze za pomocą svg2png . Następnie używany <Image>z tymi plikami PNG. Biorąc pod uwagę obecny stan SVG w React Native, nie ma ETA dla działania SVG, więc jest to najlepszy zakład, jeśli nie możesz tolerować tej obejścia.
— Sledge Hammer

3

Użyj https://github.com/kristerkari/react-native-svg-transformer

W tym pakiecie jest wspomniane, że .svgpliki nie są obsługiwane w React Native v0.57 i niższych, więc używaj .svgxrozszerzenia dla plików svg.

W przypadku sieci Web lub React-Native-Web użyj https://www.npmjs.com/package/@svgr/webpack


Aby renderować pliki svg przy użyciu oprogramowania react-native-svg-uriReact-Native w wersji 0.57 i starszych, musisz dodać następujące pliki do projektu głównego

Uwaga: zmień rozszerzenie svgnasvgx

krok 1: dodaj plik transformer.jsdo katalogu głównego projektu

// file: transformer.js

const cleanupSvg = require('./cleanup-svg');

const upstreamTransformer = require("metro/src/transformer");

// const typescriptTransformer = require("react-native-typescript-transformer");
// const typescriptExtensions = ["ts", "tsx"];

const svgExtensions = ["svgx"]

// function cleanUpSvg(text) {
//   text = text.replace(/width="([#0-9]+)px"/gi, "");
//    text = text.replace(/height="([#0-9]+)px"/gi, "");
//    return text;
// }

function fixRenderingBugs(content) {
  // content = cleanUpSvg(content); // cleanupSvg removes width and height attributes from svg
  return "module.exports = `" + content + "`";
}


module.exports.transform = function ({ src, filename, options }) {
  // if (typescriptExtensions.some(ext => filename.endsWith("." + ext))) {
  //  return typescriptTransformer.transform({ src, filename, options })
  // }

  if (svgExtensions.some(ext => filename.endsWith("." + ext))) {
    return upstreamTransformer.transform({
      src: fixRenderingBugs(src),
      filename,
      options
    })
  }

  return upstreamTransformer.transform({ src, filename, options });
}

krok 2: dodaj rn-cli.config.jsdo katalogu głównego projektu

module.exports = {
    getTransformModulePath() {
      return require.resolve("./transformer");
    },
    getSourceExts() {
      return [/* "ts", "tsx", */ "svgx"];
    }
  };

Powyższe rozwiązania sprawdzą się również w aplikacjach produkcyjnych ✅


3

Wypróbowałem wszystkie powyższe rozwiązania i inne rozwiązania poza stosem i żadne z nich nie działało dla mnie. wreszcie po długich poszukiwaniach znalazłem jedno rozwiązanie dla mojego projektu na targi.

Jeśli potrzebujesz go do pracy w expo, jednym obejściem może być użycie https://react-svgr.com/playground/ i przeniesienie rozprzestrzeniania się rekwizytów do elementu G zamiast do katalogu głównego SVG w następujący sposób:

import * as React from 'react';
import Svg, { G, Path } from 'react-native-svg';

function SvgComponent(props) {
  return (
    <Svg viewBox="0 0 511 511">
      <G {...props}>
        <Path d="M131.5 96c-11.537 0-21.955 8.129-29.336 22.891C95.61 132 92 149.263 92 167.5s3.61 35.5 10.164 48.609C109.545 230.871 119.964 239 131.5 239s21.955-8.129 29.336-22.891C167.39 203 171 185.737 171 167.5s-3.61-35.5-10.164-48.609C153.455 104.129 143.037 96 131.5 96zm15.92 113.401C142.78 218.679 136.978 224 131.5 224s-11.28-5.321-15.919-14.599C110.048 198.334 107 183.453 107 167.5s3.047-30.834 8.581-41.901C120.22 116.321 126.022 111 131.5 111s11.28 5.321 15.919 14.599C152.953 136.666 156 151.547 156 167.5s-3.047 30.834-8.58 41.901z" />
        <Path d="M474.852 158.011c-1.263-40.427-10.58-78.216-26.555-107.262C430.298 18.023 405.865 0 379.5 0h-248c-26.365 0-50.798 18.023-68.797 50.749C45.484 82.057 36 123.52 36 167.5s9.483 85.443 26.703 116.751C80.702 316.977 105.135 335 131.5 335a57.57 57.57 0 005.867-.312 7.51 7.51 0 002.133.312h48a7.5 7.5 0 000-15h-16c10.686-8.524 20.436-20.547 28.797-35.749 4.423-8.041 8.331-16.756 11.703-26.007V503.5a7.501 7.501 0 0011.569 6.3l20.704-13.373 20.716 13.374a7.498 7.498 0 008.134 0l20.729-13.376 20.729 13.376a7.49 7.49 0 004.066 1.198c1.416 0 2.832-.4 4.07-1.2l20.699-13.372 20.726 13.374a7.5 7.5 0 008.133 0l20.732-13.377 20.738 13.377a7.5 7.5 0 008.126.003l20.783-13.385 20.783 13.385a7.5 7.5 0 0011.561-6.305v-344a7.377 7.377 0 00-.146-1.488zM187.154 277.023C171.911 304.737 152.146 320 131.5 320s-40.411-15.263-55.654-42.977C59.824 247.891 51 208.995 51 167.5s8.824-80.391 24.846-109.523C91.09 30.263 110.854 15 131.5 15s40.411 15.263 55.654 42.977C203.176 87.109 212 126.005 212 167.5s-8.824 80.391-24.846 109.523zm259.563 204.171a7.5 7.5 0 00-8.122 0l-20.78 13.383-20.742-13.38a7.5 7.5 0 00-8.131 0l-20.732 13.376-20.729-13.376a7.497 7.497 0 00-8.136.002l-20.699 13.373-20.727-13.375a7.498 7.498 0 00-8.133 0l-20.728 13.375-20.718-13.375a7.499 7.499 0 00-8.137.001L227 489.728V271h8.5a7.5 7.5 0 000-15H227v-96.5c0-.521-.054-1.03-.155-1.521-1.267-40.416-10.577-78.192-26.548-107.231C191.936 35.547 182.186 23.524 171.5 15h208c20.646 0 40.411 15.263 55.654 42.977C451.176 87.109 460 126.005 460 167.5V256h-.5a7.5 7.5 0 000 15h.5v218.749l-13.283-8.555z" />
        <Path d="M283.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15zM331.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15zM379.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15zM427.5 256h-16a7.5 7.5 0 000 15h16a7.5 7.5 0 000-15z" />
      </G>
    </Svg>
  );
}

export default function App() {
  return (
    <SvgComponent width="100%" height="100%" strokeWidth={5} stroke="black" />
  );
}

1
To również działa dobrze dla mnie. Możemy łatwo uzyskać ścieżkę do pliku svg, otwierając go w przeglądarce i przeglądając źródło strony, a następnie bezpośrednio użyj ścieżki i zamień tag <path /> na react-native-svg <Path />. WIELKIE DZIĘKI
— Rakesh

1

możesz to zrobić w prosty sposób

najpierw należy przeprowadzić instalację,

  1. npm install -s respond-native-svg
  2. łącze react-natywne reaguj-natywne-svg
  3. npm install -s respond-native-svg-transformer

Następnie należy dodać następujący kod do pliku metro.config.js

const { getDefaultConfig } = require("metro-config");
module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts }
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer")
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"]
    }
  };
})();

następnie powinieneś utworzyć nowy plik w swoim katalogu głównym o nazwie declarations.d.js z następującym kodem

declare module "*.svg" {
  import { SvgProps } from "react-native-svg";
  const content: React.FC<SvgProps>;
  export default content;
}

Wreszcie, to jest mathod importu

import USER from "../../assets/icons/user.svg"

i to jest dla jsx

<USER width="100%" height="100%"/>


0

Uwaga: Svg nie działa dla wersji Androida, więc nie rozważaj dla Androida. Będzie działać tylko dla Androida w trybie debugowania. Ale działa dobrze na iOS.

Użyj https://github.com/vault-development/react-native-svg-uri

zainstalować

npm install react-native-svg-uri --save
react-native link react-native-svg # not react-native-svg-uri

Stosowanie

import SvgUri from 'react-native-svg-uri';


<SvgUri source={require('./path_to_image/image.svg')} />

@AravindVemula masz rację. Nie działa w wersjach Androida. Nie mogłem też znaleźć rozwiązania. Prawdopodobnie do tej pory nie ma rozwiązania. Porzuciłem używanie svg i wróciłem do tradycyjnego sposobu reagowania na rodzime obrazy
— Daniel Raouf

0

Używam tych dwóch wtyczek,

  1. [react-native-svg] https://github.com/react-native-community/react-native-svg )
  2. [react-native-svg-transformer] https://github.com/kristerkari/react-native-svg-transformer )

Przede wszystkim musisz zainstalować tę wtyczkę. Następnie musisz zmienić swój metro.config.js za pomocą tego kodu.

const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts }
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer")
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"]
    }
  };
})();

Aby uzyskać więcej informacji, możesz odwiedzić ten link


0

możesz przekonwertować dowolny plik SVG na komponent i uczynić go wielokrotnego użytku.

oto moja odpowiedź na najłatwiejszy sposób, w jaki możesz to zrobić

SVG do komponentu


0
import React from 'react'
import SvgUri from 'react-native-svg-uri';

export default function Splash() {
  return (
    <View style={styles.container}>
      {/* provided the svg file is stored locally */}
      <SvgUri
        width="400"
        height="200"
        source={require('./logo.svg')}
      />
      {/* if the svg is online */}
      <SvgUri
        width="200"
        height="200"
        source={{ uri: 'http://thenewcode.com/assets/images/thumbnails/homer-simpson.svg' }}
      />

      <Text style={styles.logoText}>
        Text
      </Text>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  logoText: {
    fontSize: 50
  }
});

użyj, npm install react-native-svg-uri --saveaby zainstalować potrzebny pakiet
— bello hargbola

-6

Wszystkie te rozwiązania są absolutnie okropne. Po prostu przekonwertuj plik SVG na PNG i użyj <Image/>komponentu waniliowego . Fakt, że react-native nadal nie obsługuje obrazów SVG w Imagekomponencie, to żart. Nigdy nie powinieneś instalować dodatkowej biblioteki dla tak prostego zadania. Użyj https://svgtopng.com/


1
Jest to projekt typu open source - jestem pewien, że byliby zadowoleni z twojej prośby o ściągnięcie, gdybyś miał lepsze rozwiązanie niż wspomniane powyżej ... :)
— Herald Smit
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.