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