Як показати файл SVG на React Native?


102

Я хочу показати файли 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>

Також я знаю, що рідна реакція в основному не підтримує svg, але я думаю, що хтось вирішив цю проблему хитрим способом (з / без response-native-svg)


Ви не можете використовувати use для відображення цілого файлу, для цього вам знадобиться зображення.
Роберт Лонгсон,

Так, я теж спробував @RobertLongson, але він теж не працює.
the_bluescreen

Ви можете додати його як css backgroundImage, ви пробували?
danielarend

Я спробував, але рідний компонент View не підтримує підтримку backgroundImage у стилі css. @danielarend
the_bluescreen

Я не впевнений, чому ви б використовували обгортку SVG, щоб обернути зображення SVG.
Роберт Лонгсон,

Відповіді:


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, коли я втомився від вашого рішення, я отримав цю помилку Непомітна помилка: Незмінне порушення: Тип елемента недійсний: очікується рядок (для вбудованих компонентів) або клас / функція, але отримано: об'єкт . не могли б ви мені тут допомогти?
Могутній

2
Будь-хто, хто має проблеми з використанням цього підходу, переконайтесь, що ви встановили останню версію react-native-svgпакету. Також не забудьте запустити цю команду, щоб зв’язати свій пакетreact-native link react-native-svg
connect2Coder

2
Це тривалий процес , реалізувати SVG - файли, краще використовувати github.com/kristerkari/react-native-svg-transformer як запропоновано нижче stackoverflow.com/a/55604442/1854104
hefgi

10

Я опублікував тут ще одне рішення, який є найкращим підходом для вставки векторного (svg) графіку в рідне додаток для реагування. Цей підхід використовує векторний шрифт (з svg) замість svg-файлу. PS: Він чудово працює в iOS та Android, і ви також можете змінити колір та розмір векторної піктограми.

Якщо ви хочете вставити svg безпосередньо у свій додаток, ви можете спробувати бібліотеку сторонніх розробників: response-native-svg. Маючи понад 3 тис. Зірок у github, це один із найкращих підходів.

  • встановити:
    • npm я реагую-native-svg
    • npm я реагую-native-svg-uri
  • прив’язати до рідної:
    • реагувати-рідне посилання реагувати-рідне-свг

І ось зразок:

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

Я використовував останній із джерелом = {require ('myImagePath')}, але це видає мені помилку.
Pulkit Aggarwal

1
Подивіться на відповідь, яку я розміщу тут, використовуючи шрифт замість svg. це найкраще рішення: stackoverflow.com/questions/49951885 / ...
Кассіо Seffrin

2
Ця бібліотека працює так повільно. Він обертає кожен svg у власному веб-перегляді.
JP_

1
tnx, це було найшвидше рішення, але замість svgXmlData = {testSvg} я використав source = {testSvg} працював як принада. tnx знову.
Андріс Ладузанс

9

Спробувавши багато способів і бібліотек, я вирішив створити новий шрифт (із Glyphs або цим посібником ) і додати до нього свої файли SVG, а потім використовувати компонент "Текст" із моїм користувацьким шрифтом.

Сподіваюся, це допоможе тим, хто має таку ж проблему з SVG у реакції-native.


Я думаю, ви маєте рацію, сімейство шрифтів - це, мабуть, найпростіший спосіб ввести прості svgs в рідну реакцію
Джо Ллойд,

Гарний підручник з цього питання: blog.bam.tech/developper-news/… . Потрібен пакет Вузол векторних піктограм .
Рафа

Це рішення не дійсне, якщо вам потрібно імпортувати різнокольоровий файл провисання
Джо Аспара,

Я спробував його рішення з icomoon, і це не спрацювало, ані їх підтримка активна. І Фонтелло змінює мої svgs.
Siraj Alam

6

Встановіть response-native-svg-transformer

npm я реагую-native-svg-transformer --save-dev

Я використовую SVG наступним чином, і він працює нормально

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

у візуалізації

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

Коли я імпортую файл SVG HEARTSVG із папки із зображеннями, він відображає помилку. І жодної помилки при імпорті файлів PNG. Будь-яка пропозиція?
Ракеш,

4

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

Це не ідеально, і я переглядаю його сьогодні, тому що він працює набагато гірше на Android.


Насправді це творча відповідь, але це мені не допомагає :) Оскільки я буду використовувати список піктограм (10 або більше піктограм SVG), тож, якщо я використовую це, це може бути дуже погано для продуктивності, я думаю. Що ти думаєш?
the_bluescreen

Я відтворив 10-15 свг на сторінці. Ніхто не скаржився на iOS, всі скаржилися на Android. В iOS існує затримка 0,1-0,3 секунди (спалах білого світла до початку завантаження). На Android це може становити 1 секунду, і іноді вони ніколи не завантажуються. Врешті-решт я перевірив свої SVG, а потім написав сценарій, який перетворює їх у PNG точно правильного розміру за допомогою svg2png . Потім використовується <Image>з цими PNG. Враховуючи поточний стан SVG у рідній реакції, немає часу очікування для роботи SVG, тому це найкращий вибір, якщо ви не можете терпіти роботу.
Кувалда

3

Використовуйте https://github.com/kristerkari/react-native-svg-transformer

У цьому пакеті згадується, що .svgфайли не підтримуються у React Native v0.57 і нижче, тому використовуйте .svgxрозширення для файлів svg.

Для використання в Інтернеті або для реагування на рідному веб-сайті https://www.npmjs.com/package/@svgr/webpack


Щоб відтворити svg-файли з використанням react-native-svg-uriрідної реакції версії 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 & replace (замінити <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. [response-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
  }
});

використовуйте npm install react-native-svg-uri --saveдля встановлення необхідного пакета
bello hargbola

-6

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


1
Це проект з відкритим кодом - я впевнений, що вони були б задоволені вашим запитом на витяг, якщо у вас є краще рішення, ніж згадане вище ... :)
Геральд Сміт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.