You are currently viewing “React Native에서 react-native-svg를 사용하여 SVG 파일 가져오는 방법”

“React Native에서 react-native-svg를 사용하여 SVG 파일 가져오는 방법”

React Native에서 SVG 파일을 사용하는 방법에 대해 알아보고 있는데, 여기서는 react-native-svg를 사용하여 React Native에서 SVG 파일을 가져오는 방법에 대해 설명합니다. 이 방법은 개발자가 모바일 애플리케이션에서 벡터 이미지를 효과적으로 사용할 수 있게 해주며, 더 높은 품질의 그래픽과 애니메이션을 제공합니다. 또한, 이 글에서는 react-native-animation 패키지를 활용해 SVG 애니메이션을 구현하는 방법과, React Native WebView를 통해 애니메이션된 SVG를 렌더링하는 방법에 대해서도 다룹니다. RN 프로젝트에서 SVG 파일을 간단하게 가져오는 방법에 대한 팁도 제공하므로, SVG와 관련된 작업을 보다 쉽게 처리할 수 있게 될 것입니다.

React Native 애플리케이션을 개발할 때, 아이콘을 구현해야 할 필요가 있을 수 있습니다. 이를 위해 가장 간단한 방법은 아이콘의 .png 또는 .jpeg 파일을 추출하여 React Native의 Image 컴포넌트에서 사용하는 것입니다. 이 방법은 일단 작동은 하겠지만, 높은 품질의 이미지를 얻을 수 없고, 더 큰 이미지 파일 크기로 인해 앱의 용량이 커지게 되어 앱 번들의 크기가 증가하게 됩니다.

React Native 앱에서 .png 또는 .jpeg 파일을 사용하는 대신, SVG 포맷을 사용해야 합니다. SVG는 벡터 기반 포맷으로, 품질을 저하시키지 않고 무한히 확대할 수 있습니다.

이 가이드에서는 react-native-svg 라이브러리를 사용하여 React Native 앱에서 SVG 아이콘을 구현하는 방법을 배워보겠습니다.

SVG(Scalable Vector Graphics)는 벡터 이미지를 렌더링하기 위해 사용되는 XML 기반의 포맷입니다. 벡터 이미지는 수학적 방정식을 사용하고 .png나 .jpeg와 같은 다른 이미지 포맷처럼 픽셀이 없기 때문에, 원하는 만큼 확대해도 화질이 떨어지지 않습니다.

SVG 포맷의 벡터 특성으로 인해, 이미지는 해상도에 독립적입니다. 새로운 스마트폰에 있는 화려한 285 DPI 픽셀 밀도 화면부터 표준 모니터의 85 DPI 화면까지, 모든 화면에서 SVG 이미지는 선명하게 보입니다. SVG 파일은 또한 다른 이미지 포맷에 비해 파일 크기도 작습니다.

텍스트 편집기에서 SVG 파일을 열면, 숫자와 다양한 노드로 구성된 큰 XML 코드를 볼 수 있습니다. 이 튜토리얼에서는 SVG 자체에 집중하지 않을 것입니다. 대신, 모바일 앱 화면에 SVG를 렌더링하는 방법을 보여드릴 것입니다.

React Native는 SVG를 지원하나요?

모바일 앱에서 SVG를 렌더링하는 것은 웹에서 SVG를 이미지 소스로 직접 사용하거나 SVG 코드를 HTML 파일에 붙여넣는 것만큼 간단하지 않습니다. 이는 React Native에 SVG를 직접 렌더링할 수 있는 내장 컴포넌트가 없기 때문입니다.

React Native가 기본적으로 SVG를 지원하지 않기 때문에, npm 패키지 저장소에서 몇 가지 라이브러리를 설치해야 합니다. 다행히도, 대부분의 사용 사례에 잘 작동하는 인기 있는 npm 패키지인 react-native-svg가 있습니다.

React Native 프로젝트를 설정해봅시다. 다음 명령을 실행하세요:

npx react-native init SvgDemoApp

react-native-svg와 react-native-svg-transformer 패키지를 설치하려면 프로젝트 디렉토리로 이동한 후 다음 명령을 실행하세요:

cd SvgDemoApp
npm i react-native-svg
npm i --save-dev react-native-svg-transformer

react-native-svg는 Android와 iOS 플랫폼 모두에서 React Native 프로젝트에 SVG 지원을 제공합니다. react-native-svg-transformer를 사용하면 웹에서 Create React App 프로젝트를 하듯이 React Native 프로젝트에서 로컬 SVG 파일을 가져올 수 있습니다.

React Native CLI 대신 Expo CLI를 사용하는 경우 다음 명령을 실행하여 시작할 수 있습니다:

expo init SvgDemoApp
expo install react-native-svg

React Native에서 SVG 모양 렌더링하기
이제 react-native-svg 라이브러리를 사용하여 앱에서 SVG를 렌더링하는 방법을 살펴보겠습니다.

선호하는 텍스트 편집기에서 프로젝트 디렉토리를 열고 react-native-svg에서 Svg와 Circle 컴포넌트를 다음과 같이 가져옵니다:

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

컴포넌트는 모든 SVG 모양을 렌더링하기 위해 필요한 부모 컴포넌트입니다. 이것은 모든 SVG 모양을 위한 컨테이너 컴포넌트와 같습니다. 원이나 다각형과 같은 SVG 모양을 렌더링하는 경우, SVG 컴포넌

트 주변에 이것을 래퍼로 사용해야 합니다:

<Svg height="50%" width="50%" viewBox="0 0 100 100" >
       ...
</Svg>

컴포넌트는 세 가지 속성을 받습니다: height, width, 그리고 viewBox. viewBox 속성은 SVG를 공간에 어떻게 배치할지를 설명합니다. height와 width 속성은 자명합니다.

컴포넌트 내부에 컴포넌트를 다음과 같이 렌더링하세요:

<Svg height="50%" width="50%" viewBox="0 0 100 100" >
    <Circle cx="50" cy="50" r="50" stroke="purple" strokeWidth=".5" fill="violet" />
</Svg>

컴포넌트는 x와 y 좌표를 각각 cx와 cy 속성으로 받습니다. 이 좌표들은 SVG 컴포넌트가 컨테이너 내에서 어떻게 그리고 어디에 배치될지를 정의합니다. 다른 SVG 모양을 렌더링하는 경우, 예를 들어 사각형은 각각 x와 y 속성으로 표현됩니다.

원의 반지름을 설명하기 위해, r 속성에 문자열로 정수를 전달할 수 있습니다. 이 값을 설정하여 렌더링된 SVG 원의 크기를 증가시키거나 감소시킬 수 있습니다.

stroke 속성은 SVG 요소 주변의 테두리 색상을 나타내는 데 사용될 수 있으며, strokeWidth는 그 테두리의 두께를 나타냅니다. 마지막으로, fill 속성은 렌더링된 SVG 요소의 색상을 나타냅니다. 이 속성들은 네이티브 HTML 요소의 속성과 유사하며 대부분의 SVG 컴포넌트에서 공통적입니다.

화면에 SVG 원을 렌더링하는 전체 코드를 살펴보겠습니다:

import React from 'react';
import { StyleSheet, View } from 'react-native';
import Svg, { Circle } from 'react-native-svg';

export default function App() {
  return (
    <View style={styles.container}>
      <Svg height="50%" width="50%" viewBox="0 0 100 100" >
        <Circle cx="50" cy="50" r="50" stroke="purple" strokeWidth=".5" fill="violet" />
      </Svg>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

위 코드를 실행하면 아래와 같은 보라색 SVG 원이 보여야 합니다:

React Native SVG 원 모양 예시

컴포넌트를 컴포넌트 안에 넣은 것을 확인할 수 있습니다. SVG 컴포넌트를 와 같은 일반적인 컨테이너 컴포넌트나 다른 사용자 정의 래퍼 컴포넌트 안에 넣을 수 있습니다. 이를 통해 위의 예시처럼 flexbox 레이아웃을 사용하여 화면의 어느 곳에나 SVG 컴포넌트를 배치하고 위치시킬 수 있습니다.

마찬가지로, 사각형, 다각형, 선, 타원 등 다른 SVG 모양도 렌더링할 수 있습니다. 하지만 react-native-svg가 아직 모든 SVG 요소를 지원하지 않는다는 점을 알고 있어야 합니다.

위의 예시처럼 기본적인 SVG 모양을 만들 때만 지원되는 SVG 요소를 조합할 수 있습니다. 실제 애플리케이션에서는 SVGR과 같은 온라인 도구를 사용할 수 있습니다.

SVG 코드를 온라인 SVGR 플레이그라운드에 복사하여 붙여넣습니다. 그러면 SVG가 react-native-svg와 함께 사용할 수 있는 React 컴포넌트로 변환됩니다.

이제 react-native-svg 라이브러리를 사용하여 SVG를 생성하고 렌더링하는 방법을 이해했으니, URI에서 로드된 SVG 아이콘과 이미지를 렌더링하는 방법을 알아보겠습니다.

여기서는 SvgUri라는 다른 컴포넌트를 사용해야 하므로 라이브러리에서 이를 가져오겠습니다:

import { SvgUri } from 'react-native-svg';

컴포넌트는 width, height 및 uri 속성을 받습니다. uri 속성에 SVG의 URL을 가리키도록 지정할 수 있습니다. 예를 들어, 이 SVG를 렌더링하려면 아래와 같이 컴포넌트의 uri 속성에 해당 URL을 할당할 수 있습니다:

<SvgUri
    width="100%"
    height="100%"
    uri="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/debian.svg"
/>

이는 React에서 이미지를 렌더링할 때 의 src 속성을 이미지의 URL로 지정하는 것과 유사합니다.

위 코드는 아래와 같이 화면에 SVG를 렌더링해야 합니다:

React Native SVG 아이콘 예시

컴포넌트의 width 및 height 속성을 사용하여 SVG의 너비와 높이를 조정할 수 있습니다. SVG 모양을 렌더링할 때와 달리 여기서는 컨테이너 컴포넌트가 필요하지 않습니다.

react-native-svg-transformer 사용하기
이전 섹션에서는 React Native 애플리케이션에서 react-native-svg를 사용하여 SVG를 생성하고 렌더링하는 방법을 탐색했습니다. 그러나 경우에 따라 프로젝트 내부에 로컬 SVG 아이콘이나 이미지를 참조해야 할 수도 있습니다.

예제 프로젝트를 설정할 때 react-native-svg-transformer를 개발 의존성으로 설치했음을 기억하세요. 이를 사용하여 프로젝트 내부에 로컬 SVG 아이콘이나 이미지를 렌더링할 수 있습니다.

react-native-svg-transformer를 사용하면 원시 SVG 자산을 React 컴포넌트로 가져올 수 있습니다. 이는 SVG를 react-native-svg와 호환되는 형식으로 변환합니다.

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

다음으로, 원하는 SVG를 다운로드하여 프로젝트 안에 저장하세요. 이미지를 다운로드하는 것과 유사한 방법으로 진행합니다. SVG 파일을 image.svg라고 이름지었다고 가정해봅시다. 이제 이 SVG 파일을 다른 React 컴포넌트처럼 가져올 수 있습니다:

import SVGImg from './image.svg';

그리고 아래와 같이 컴포넌트 안에 렌더링하세요:

<SVGImg width={200} height={200} />

위 코드는 화면에 동일한 SVG를 렌더링해야 합니다. 프로젝트에서 로컬에 SVG 아이콘을 렌더링해야 하는 경우, 이 접근 방식을 따라 다양한 SVG 아이콘을 앱에 렌더링할 수 있습니다.

XML 문자열을 사용하여 SVG 렌더링하기
드문 경우지만, react-native-svg-transformer를 사용하여 로컬 SVG를 참조할 수 없는 경우, React Native 앱에서 XML 문자열을 사용하여 SVG를 렌더링할 수 있습니다.

프로젝트에 다른 예제 SVG를 다운로드했다고 가정해봅시다. VS Code와 같은 텍스트 편집기에서 SVG 파일을 보면, HTML 요소를 포함한 XML 코드를 볼 수 있습니다. 컴포넌트를 사용하여 XML 코드에서 직접 SVG를 렌더링할 수 있습니다:

import { SvgXml } from 'react-native-svg';

SVG 파일의 XML 코드에서 요소 안의 모든 것을 복사하여 문자열 변수 안에 저장하세요.

const xml = `
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
...
</svg>
`;

그런 다음, 아래와 같이 컴포넌트 안의 xml prop에 위 변수를 전달하세요:

<SvgXml xml={xml} width="100%" height="100%" />

그러면 이제 화면에 다음 SVG가 보여야 합니다:

React Native SVG 호머 심슨 예제

React Native에서 SVG 애니메이션 구현하기
SVG를 사용하는 장점 중 하나는 JavaScript와 CSS를 사용하여 애니메이션을 적용할 수 있다는 것입니다. 그러나 React Native에는 고성능 SVG 애니메이션 기능이 내장되어 있지 않습니다. 따라서 SVG 애니메이션을 구현하는 것은 간단하지 않을 수 있습니다.

이 섹션에서는 SVG를 사용하여 React Native에서 동적이고 상호 작용적인

그래픽을 추가하는 데 사용할 수 있는 몇 가지 기법을 탐색할 것입니다.

위의 코드에서는 react-native-reanimated를 사용하여 애니메이션을 만들고 있습니다. 이를 사용하면 SVG의 반경과 불투명도를 애니메이션화하여 원의 펄스 효과를 만들 수 있습니다.

먼저, react-native-reanimated를 npm 패키지 레지스트리에서 설치해야 합니다. 다음 중 하나의 명령을 사용하여 설치할 수 있습니다:

# npm
npm install react-native-reanimated

# yarn
yarn add react-native-reanimated

# expo
npx expo install react-native-reanimated

React Native Reanimated를 성공적으로 설치한 후에는, babel.config.js 파일에 react-native-reanimated/plugin 플러그인을 추가해야 합니다. 다음과 같이 하세요:

module.exports = {
  presets: [
    ... // 여기에 추가하지 마세요
  ],
  plugins: [
    ...
    // 리스트의 마지막에 추가해야 합니다
    'react-native-reanimated/plugin'
  ]
};

위와 같은 babel 플러그인을 추가한 후에는 Metro 번들러 캐시를 재설정하는 것이 좋습니다. 다음 중 하나의 명령을 사용하여 실행하세요:

# npm
npm start -- --reset-cache

# yarn
yarn start --reset-cache

# expo
npx expo start -c

만약 안드로이드용으로 개발 중이라면, React Native Reanimated를 사용하기 위해서 필요한 것이 이것입니다. 그러나 iOS용으로 개발 중이라면, 다음과 같이 pod를 설치해야 합니다:

cd ios && pod install

이제 위에서 만든 보라색 원을 애니메이션화하는 작업을 진행해보겠습니다. 반경과 불투명도를 애니메이션화하여 펄스 효과를 만들 것입니다. 컴포넌트 파일을 생성하고, 다음의 코드를 복사하여 붙여넣으세요:

import React, { useEffect } from 'react';
import Svg, { Circle } from 'react-native-svg';
import Animated, {
  useSharedValue,
  useAnimatedProps,
  withRepeat,
  withTiming,
  Easing,
} from 'react-native-reanimated';

const AnimatedSVGCircle = Animated.createAnimatedComponent(Circle);

function AnimatedPulseCircle() {
  const pulse = useSharedValue(0);

  const style = useAnimatedProps(() => {
    return {
      r: 10 + pulse.value * 35,
      opacity: 1 - pulse.value,
    };
  });

  useEffect(() => {
    pulse.value = withRepeat(
      withTiming(1, { duration: 800, easing: Easing.linear }),
      -1,
      false,
    );
  }, [pulse]);

  return (
    <Svg width={100} height={100}>
      <AnimatedSVGCircle
        cx={50}
        cy={50}
        r={50}
        stroke="purple"
        strokeWidth=".5"
        fill="violet"
        animatedProps={style}
      />
    </Svg>
  );
}

export default AnimatedPulseCircle;

위 코드에서는 react-native-svg의 Circle 요소를 감싸기 위해 createAnimatedComponent를 사용했습니다. 컴포넌트와 관련된 props 또는 스타일을 애니메이션화하려면 위와 같이 컴포넌트를 감싸야 합니다.

useSharedValue Hook은 React Native Reanimated의 내장 훅 중 하나입니다. 컴포넌트 내에서 공유 값(Shared Value)을 정의하는 데 사용됩니다. 이는 단일 value 속성을 갖는 객체를 반환합니다. 이 value 속성을 직접 액세스하고 수정할 수 있습니다. 위 예제에서는 useEffect Hook에서 withRepeat 애니메이션 수정자에서 반환된 애니메이션 객체에 값을 설정하고 있습니다.

React Native Reanimated에서 애니메이션 수정자는 애니메이션을 사용자 정의하는 데 사용되는 고차 함수입니다. React Native Reanimated에는 여러 내장 애니메이션 수정자가 있습니다. 그 중 하나가 withRepeat입니다. 이름에서 알 수 있듯이 withRepeat은 애니메이션을 여러 번 반복하는 데 사용됩니다. 위 예제에서는 애니메이션을 무한히 반복하도록 설정했습니다.

useAnimatedProps Hook은 애니메이션화된 속성 객체를 생성합니다. 이는 서드파티 컴포넌트의 속성을 애니메이션화하는 데 사용됩니다. 위 예제에서는 반환된 객체를 컴포넌트의 animatedProps 값으로 전달했습니다.

위 컴포넌트를 렌더링하면 다음과 같은 애니메이션이 나타납니다:

React Native WebView를 사용하면 React Native에서 애니메이션화된 SVG를 렌더링할 수도 있습니다. 먼저 npm 패키지 레지스트리에서 React Native WebView를 설치해야 합니다:

npm install react-native-webview

SVGator의 온라인 도구를 사용하여 SVG 애니메이션을 생성하고, React Native WebView를 사용하여 React Native 프로젝트에 임베드할 수 있습니다. 온라인 도구에는 애니메이션된 SVG를 React Native용으로 내보내는 기능이 기본으로 제공됩니다.

SVG 애니메이션을 생성한 후에는 해당 코드를 React Native 프로젝트에 복사하여 붙여넣고 생성된 컴포넌트를 렌더링하면 됩니다. SVGator 문서를 확인하여 SVG 애니메이션을 만드는 방법을 배울 수 있습니다.

저는 SVGator에서 예제 SVG 애니메이션 중 하나를 내보냈습니다. 아래 GIF는 생성된 컴포넌트를 렌더링한 후의 모습을 보여줍니다:

Animated SVG clock

결론적으로, SVG는 React Native 앱에서 사용할 이미지와 아이콘을 렌더링하는 데 매우 유용합니다. 또한 복잡한 모양과 패턴을 생성하여 앱의 디자인에 더 많은 미적 요소를 추가할 수 있습니다.

그러나 로컬에 많은 수의 SVG 파일을 저장하면 여전히 앱의 크기가 커질 수 있습니다. 따라서 프로젝트에 많은 수의 SVG 파일을 저장하고 로컬에서 참조하는 것은 피해야 합니다. 필요하다면 SVG 파일을 최적화하여 사용하는 것이 좋습니다.

이 튜토리얼이 React Native 프로젝트에서 SVG를 사용하는 것을 보다 쉽게 만들어 줄 것을 기대합니다. 또한 react-native-svg 공식 문서에 있는 예제를 살펴보고 실험해 볼 수도 있습니다.

답글 남기기