Как показать файл SVG в React Native?

104

Я хочу показать файлы svg (у меня есть куча изображений svg), но то, что я не мог найти, как показать. Я пробовал использовать компоненты Image и Use из react-native-svg, но они с этим не работают. И я попытался сделать это родным способом, но показать только изображение svg очень сложно.

Пример кода:

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

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

Также я знаю, что собственный response не поддерживает svg в основном, но я думаю, что кто-то исправил эту проблему хитрым способом (с / без response-native-svg)

the_bluescreen
источник
Вы не можете использовать use для отображения всего файла, для этого вам понадобится изображение.
Роберт Лонгсон 08
Да, я тоже пробовал @RobertLongson, но это тоже не работает.
the_bluescreen 08
Вы можете добавить это как css backgroundImage, вы пробовали?
danielarend 08
Я пробовал, но реагирую, собственный компонент View не поддерживает опору backgroundImage в стиле css. @danielarend
the_bluescreen 08
Я не уверен, зачем вам использовать оболочку SVG для обертывания изображения SVG.
Роберт Лонгсон 08

Ответы:

70

Я использовал следующее решение:

  1. Конвертируйте .svgизображение в JSX с помощью https://svg2jsx.herokuapp.com/
  2. Преобразуйте JSX в react-native-svgкомпонент с https://svgr.now.sh/ (установите флажок «React Native»)
Игорь Бурлаченко
источник
Как тогда использовать этот Компонент? Вы можете поделиться кодом?
Индранил Датта,
Если вы перейдете по этой ссылке, то увидите пример с импортом svgr.now.sh ( установите флажок «React Native»). Используйте его как обычный компонент React, поместите его вместо <Image src = {...} /> и он должен работать.
Игорь Бурлаченко
1
@IhorBurlachenko, когда мне надоело ваше решение, я получил эту ошибку Неперехваченная ошибка: инвариантное нарушение: недопустимый тип элемента: ожидалась строка (для встроенных компонентов) или класс / функция, но получил: объект . не могли бы вы помочь мне здесь?
Mighty
2
Всем, у кого есть проблемы с использованием этого подхода, убедитесь, что вы установили последнюю версию react-native-svgpackage. Также не забудьте запустить эту команду, чтобы связать ваш пакетreact-native link react-native-svg
connect2Coder
2
Это долгий процесс реализации файлов SVG, лучше использовать github.com/kristerkari/react-native-svg-transformer, как предлагается ниже stackoverflow.com/a/55604442/1854104
hefgi
10

Я разместил здесь другое решение. Это лучший подход для вставки векторного (svg) графика в собственное приложение React. Этот подход использует векторный шрифт (из svg) вместо файла svg. PS: Он отлично работает на ios и android, и вы также можете изменить цвет и размер своего векторного значка.

Если вы хотите вставить svg прямо в свое приложение, вы можете попробовать стороннюю библиотеку: response-native-svg. С более чем 3000 звезд в github это один из лучших подходов.

  • установить:
    • npm я реагирую-native-svg
    • npm я реагирую-родной-svg-uri
  • ссылка на родной:
    • реагировать-родная ссылка реагировать-родной-SVG

А вот образец:

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}
  />
);
Кассио Сеффрин
источник
Выдает ошибку «невозможно добавить дочерний элемент, у которого нет узла css, к узлу без функции измерения».
Pulkit Aggarwal
Я использовал последний с source = {require ('myImagePath')}, но он дает мне ошибку.
Pulkit Aggarwal,
1
Посмотрите ответ, который я публикую здесь, используя шрифт вместо svg. это лучшее решение: stackoverflow.com/questions/49951885/…
Cassio Seffrin
2
Эта библиотека такая медленная. Он помещает каждый SVG в отдельный веб-просмотр.
JP_
1
tnx, это было самое быстрое решение, но вместо svgXmlData = {testSvg} я использовал source = {testSvg}, работало отлично. tnx снова.
Андрис Ладузанс
9

Попробовав множество способов и библиотек, я решил создать новый шрифт (с помощью Glyphs или этого руководства ) и добавить к нему мои файлы SVG, а затем использовать компонент «Текст» с моим настраиваемым шрифтом.

Надеюсь, это поможет любому, у кого такая же проблема с SVG в react-native.

Амир Хорсанди
источник
Я думаю, что вы правы, семейство шрифтов, вероятно, самый простой способ превратить простые SVG в React Native
Джо Ллойд
Хороший учебник по этой теме: blog.bam.tech/developper-news/… . Требуется пакет узла векторных иконок .
Rafa
Это решение недействительно, если вам нужно импортировать многоцветный файл sag
Джо Аспара
Я пробовал это решение с помощью icomoon, и это не сработало, ни их поддержка не активна. И фонтелло меняет мои svgs.
Сирадж Алам
6

Установите react-native-svg-transformer

npm я реагирую-родной-SVG-трансформатор --save-dev

Я использую SVG следующим образом, и он отлично работает

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

в рендере

<View>
  <LOGOSVG 
    width="100%"
    height="70%"
  />
</View>
AndroConsis
источник
Когда я импортирую файл SVG HEARTSVG из папки изображений, он показывает ошибку. И нет ошибки при импорте файлов png. Любое предложение?
Ракеш
4

У меня такая же проблема. Я использую это решение, которое я нашел: React Native display SVG из файла

Он не идеален, и я возвращаюсь к нему сегодня, потому что он работает намного хуже на Android.

Кувалда
источник
На самом деле это творческий ответ, но он мне не подходит :) Потому что я буду использовать список значков (10 или более значков SVG), поэтому, если я использую его, это может быть очень плохо для производительности, я думаю. Что вы думаете?
the_bluescreen
Я отрендерил 10-15 SVG на странице. Никто не жаловался на iOS, все жаловались на Android. В iOS задержка составляет 0,1–0,3 секунды (белая вспышка перед загрузкой). На Android это может быть 1 секунда, а иногда они никогда не загружаются. В конце концов, я проверил свои SVG-файлы, а затем написал сценарий, который преобразует их в PNG- файлы точно правильного размера с помощью svg2png . Затем используется <Image>с этими PNG. Учитывая текущее состояние SVG в react native, ETA для SVG не работает, так что это лучший вариант, если вы не можете терпеть эту работу.
Sledge Hammer
3

Используйте https://github.com/kristerkari/react-native-svg-transformer

В этом пакете упоминается, что .svgфайлы не поддерживаются в React Native v0.57 и ниже, поэтому используйте .svgxрасширение для файлов svg.

Для Интернета или response-native-web используйте https://www.npmjs.com/package/@svgr/webpack


Для рендеринга файлов svg react-native-svg-uriс использованием react-native версии 0.57 и ниже вам необходимо добавить следующие файлы в ваш корневой проект

Примечание: измените расширение svgнаsvgx

шаг 1: добавить файл transformer.jsв корень проекта

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

шаг 2: добавить rn-cli.config.jsв корень проекта

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

Вышеупомянутые решения будут работать и в производственных приложениях ✅

Аравинд Вемула
источник
2

Я пробовал все вышеперечисленные решения и другие решения вне стека, и ни один из них не работал у меня. наконец, после долгих исследований я нашел одно решение для своего выставочного проекта.

Если вам нужно, чтобы он работал в expo, одним из обходных путей может быть использование https://react-svgr.com/playground/ и перемещение распространения реквизита в элемент G вместо корня SVG следующим образом:

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" />
  );
}
Акшай Италия
источник
Это тоже хорошо работает для меня. Мы можем легко получить путь к svg-файлу, открыв его в браузере и просмотреть исходный код страницы, а затем напрямую использовать путь и заменить тег <path /> на response-native-svg <Path />. ОГРОМНОЕ СПАСИБО
Ракеш
0

Примечание: Svg не работает для версий Android, поэтому не рассматривайте для Android. Он будет работать для Android только в режиме отладки. Но на ios работает нормально.

Используйте https://github.com/vault-development/react-native-svg-uri

Установить

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

Применение

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


<SvgUri source={require('./path_to_image/image.svg')} />
Даниэль Рауф
источник
@AravindVemula, вы правы. Это не работает для версий Android. Я тоже не нашел решения. Наверное, до сих пор нет решения. Я отказался от использования svg и вернулся к традиционному способу реагирования на нативные изображения
Даниэль Рауф
0

Я использую эти два плагина,

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

Прежде всего, вам необходимо установить этот плагин. После этого вам нужно изменить свой 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"]
    }
  };
})();

Более подробную информацию вы можете найти по этой ссылке.

Ганда Рейн Панджайтан
источник
0

вы можете преобразовать любой SVG в компонент и сделать его многоразовым.

вот мой ответ на самый простой способ сделать это

SVG в компонент

Анас
источник
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
  }
});
Bello Hargbola
источник
используйте npm install react-native-svg-uri --saveдля установки необходимого пакета
bello hargbola
-6

Все эти решения абсолютно ужасны. Просто конвертируйте свой SVG в PNG и используйте ванильный <Image/>компонент. Тот факт, что react-native по-прежнему не поддерживает изображения SVG в Imageкомпоненте, - это шутка. Никогда не устанавливайте дополнительную библиотеку для такой простой задачи. Используйте https://svgtopng.com/

YungGun
источник
1
Это проект с открытым исходным кодом - я уверен, что они будут довольны вашим запросом на перенос, если у вас есть решение получше, чем упомянуто выше ... :)
Herald Smit