Wie zeige ich eine SVG-Datei auf React Native?


93

Ich möchte SVG-Dateien anzeigen (ich habe eine Reihe von SVG-Bildern), aber das, was ich nicht zeigen konnte. Ich habe versucht, Image and Use- Komponenten von react-native-svg zu verwenden, aber damit funktionieren sie nicht. Und ich habe versucht, das auf native Weise zu tun, aber es ist wirklich harte Arbeit, nur ein SVG-Bild zu zeigen.

Beispielcode:

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

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

Ich weiß auch, dass der React Native SVG im Grunde nicht unterstützt, aber ich denke, jemand hat dieses Problem auf knifflige Weise behoben (mit / ohne React-Native-SVG).


Sie können nicht verwenden, um eine ganze Datei anzuzeigen, dafür benötigen Sie ein Bild.
Robert Longson

Ja, ich habe es auch versucht @RobertLongson, aber es funktioniert auch nicht.
the_bluescreen

Sie können es als CSS-Hintergrundbild hinzufügen. Haben Sie es versucht?
Danielarend

Ich habe versucht, aber reagieren native View-Komponente unterstützt nicht backgroundImage Prop auf CSS-Stil. @ Danielielend
the_bluescreen

Ich bin mir nicht sicher, warum Sie einen SVG-Wrapper verwenden würden, um ein SVG-Bild zu verpacken.
Robert Longson

Antworten:


63

Ich habe die folgende Lösung verwendet:

  1. Konvertieren Sie das .svgBild mit https://svg2jsx.herokuapp.com/ in JSX.
  2. Konvertieren Sie die JSX- react-native-svgKomponente mit https://svgr.now.sh/ in eine Komponente (aktivieren Sie das Kontrollkästchen "Native reagieren").

Wie benutzt man diese Komponente dann? Können Sie einen Code teilen?
Indranil Dutta

Wenn Sie diesem Link folgen, wird ein Beispiel mit den Importen svgr.now.sh angezeigt ( aktivieren Sie das Kontrollkästchen "Native reagieren "). Verwenden Sie es als reguläre React-Komponente und platzieren Sie es anstelle von <Image src = {...} /> und es sollte funktionieren.
Ihor Burlachenko

1
@IhorBurlachenko Als ich Ihre Lösung müde gemacht habe, habe ich diesen Fehler erhalten. Nicht erfasster Fehler: Invariante Verletzung: Elementtyp ist ungültig: Erwartet eine Zeichenfolge (für integrierte Komponenten) oder eine Klasse / Funktion, hat aber: Objekt . Könntest du mir hier helfen?
Mächtiger

2
Wenn Sie Probleme mit diesem Ansatz haben, stellen Sie bitte sicher, dass Sie die neueste Version des react-native-svgPakets installieren . react-native link react-native-svg
Stellen Sie

2
Dies ist ein langer Prozess zum Implementieren von SVG-Dateien. Verwenden Sie besser github.com/kristerkari/react-native-svg-transformer, wie unten vorgeschlagen. Stackoverflow.com/a/55604442/1854104
hefgi

9

Ich habe hier eine andere Lösung veröffentlicht. Dies ist der beste Ansatz zum Einfügen eines Vektordiagramms (svg) in eine native Reaktionsanwendung . Bei diesem Ansatz wird eine Vektorschrift (aus svg) anstelle einer svg-Datei verwendet. PS: Es funktioniert hervorragend in iOS und Android, und Sie können auch die Farbe und Größe Ihres Vektorsymbols ändern.

Wenn Sie eine SVG-Datei direkt in Ihre App einfügen möchten, können Sie eine Bibliothek eines Drittanbieters ausprobieren: react-native-svg. Mit mehr als 3.000 Sternen in Github ist dies einer der besten Ansätze.

  • Installieren:
    • npm ich reagiere-native-svg
    • npm ich reagiere-native-svg-uri
  • verknüpfe das mit native:
    • React-Native Link React-Native-SVG

Und hier ist ein Beispiel:

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}
  />
);

Es gibt den Fehler "Ein Kind ohne Messfunktion kann kein untergeordnetes Element hinzufügen, das keinen CSS-Knoten hat".
Pulkit Aggarwal

Ich habe den letzten mit source = {require ('myImagePath')} verwendet, aber es gibt mir einen Fehler.
Pulkit Aggarwal

1
Schauen Sie sich die Antwort an, die ich hier poste, und verwenden Sie stattdessen eine Schriftart als SVG. Es ist eine bessere Lösung: stackoverflow.com/questions/49951885/…
Cassio Seffrin

2
Diese Bibliothek ist so langsam. Es verpackt jedes SVG in eine eigene Webansicht.
JP_

1
tnx, das war die schnellste Lösung, aber anstelle von svgXmlData = {testSvg} habe ich source = {testSvg} verwendet und wie ein Zauber funktioniert. tnx wieder.
Andris Laduzans

8

Nachdem ich viele Möglichkeiten und Bibliotheken ausprobiert hatte, entschied ich mich, eine neue Schriftart (mit Glyphen oder diesem Tutorial ) zu erstellen , meine SVG-Dateien hinzuzufügen und dann die Komponente "Text" mit meiner benutzerdefinierten Schriftart zu verwenden.

Hoffe, dies hilft jedem, der das gleiche Problem mit SVG in React-Native hat.


Ich denke, Sie haben Recht, eine Schriftfamilie ist wahrscheinlich der einfachste Weg, um einfache SVGs dazu zu bringen, native zu reagieren
Joe Lloyd

Nettes Tutorial zu diesem Thema: blog.bam.tech/developper-news/… . Benötigt das Vector Icons Node-Paket.
Rafa

Diese Lösung ist nicht gültig, wenn Sie mehrfarbige Sag-Dateien importieren müssen
Joe Aspara

Ich habe seine Lösung mit icomoon ausprobiert und es hat nicht geklappt, und ihre Unterstützung ist nicht aktiv. Und Fontello verändert meine SVGs.
Siraj Alam

6

Installieren Sie den React-Native-SVG-Transformator

npm ich reagiere-native-svg-transformator --save-dev

Ich benutze SVG wie folgt und es funktioniert gut

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

in rendern

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

4

Ich hatte das gleiche Problem. Ich verwende diese Lösung, die ich gefunden habe: Reagiere native Anzeige-SVG aus einer Datei

Es ist nicht perfekt und ich besuche es heute noch einmal, weil es unter Android viel schlechter abschneidet.


Eigentlich ist es eine kreative Antwort, aber es hilft meinen Passungen nicht :) Da ich eine Symbolliste (10 oder mehr SVG-Symbole) verwende, kann es für die Leistung sehr schlecht sein, denke ich. Was denken Sie?
the_bluescreen

Ich habe 10-15 SVGs auf einer Seite gerendert. Niemand hat sich über iOS beschwert, alle über Android. Unter iOS gibt es eine Verzögerung von 0,1 bis 0,3 Sekunden (ein weißer Sekundenbruchteil vor dem Laden). Unter Android kann es 1 Sekunde dauern, und manchmal werden sie nie geladen. Am Ende habe ich meine SVGs eingecheckt und dann ein Skript geschrieben, das sie mit svg2png in PNGs mit genau der richtigen Größe konvertiert . Dann <Image>mit diesen PNGs verwendet. Angesichts des aktuellen Status von SVG in React Native gibt es keine ETA für SVGs. Dies ist also die beste Wahl, wenn Sie die Umgehung nicht tolerieren können.
Sledge Hammer

3

Verwenden Sie https://github.com/kristerkari/react-native-svg-transformer

In diesem Paket wird erwähnt, dass .svgDateien in React Native v0.57 und niedriger nicht unterstützt werden. Verwenden Sie daher die .svgxErweiterung für SVG-Dateien.

Verwenden Sie für Web oder React-Native-Web https://www.npmjs.com/package/@svgr/webpack


Um SVG-Dateien react-native-svg-urimit der reaktionsnativen Version 0.57 und niedriger zu rendern , müssen Sie Ihrem Stammprojekt die folgenden Dateien hinzufügen

Hinweis: Ändern Sie die Erweiterung svginsvgx

Schritt 1: Datei transformer.jszum Stammverzeichnis des Projekts hinzufügen

// 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 });
}

Schritt 2: rn-cli.config.jsZum Stammverzeichnis des Projekts hinzufügen

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

Die oben genannten Lösungen funktionieren auch in Produktions-Apps ✅


0

Hinweis: Svg funktioniert nicht für Android-Release-Versionen, berücksichtigen Sie es also nicht für Android. Es funktioniert für Android nur im Debug-Modus. Aber es funktioniert gut für ios.

Verwenden Sie https://github.com/vault-development/react-native-svg-uri

Installieren

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

Verwendung

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


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

@AravindVemula du hast recht. Es funktioniert nicht für Android-Release-Versionen. Ich konnte auch keine Lösung finden. Wahrscheinlich gibt es bis jetzt keine Lösung. Ich gab die Verwendung von SVG auf und wandte mich wieder der traditionellen Art zu, native Bilder zu reagieren
Daniel Raouf,

0

Ich habe alle oben genannten Lösungen und andere Lösungen außerhalb des Stapels ausprobiert und keine für mich gearbeitet. Nach langer Recherche habe ich endlich eine Lösung für mein Ausstellungsprojekt gefunden.

Wenn Sie es benötigen, um in expo zu arbeiten, besteht eine Problemumgehung darin, https://react-svgr.com/playground/ zu verwenden und die Verbreitung von Requisiten auf ein G-Element anstelle des SVG-Stamms wie folgt zu verschieben:

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" />
  );
}

0

Ich benutze diese beiden Plugins,

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

Zunächst müssen Sie dieses Plugin installieren. Danach müssen Sie Ihre metro.config.js mit diesem Code ändern.

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"]
    }
  };
})();

Für weitere Informationen können Sie diesen Link besuchen


-6

Alle diese Lösungen sind absolut schrecklich. Konvertieren Sie einfach Ihr SVG in ein PNG und verwenden Sie die Vanille- <Image/>Komponente. Die Tatsache, dass React-Native SVG-Bilder in der ImageKomponente immer noch nicht unterstützt, ist ein Witz. Sie sollten niemals eine zusätzliche Bibliothek für eine so einfache Aufgabe installieren. Verwenden Sie https://svgtopng.com/


1
Es ist ein Open-Source-Projekt - ich bin sicher, sie würden sich über Ihre Pull-Anfrage freuen, wenn Sie eine bessere Lösung als oben erwähnt haben ... :)
Herald Smit
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.