🖥️ Frontend/ReactNative

[ReactNative] svg 적용하기

우다 2024. 7. 17. 11:48

색상의 변경이 일어나는 이미지의 경우 svg를 사용하는 것을 선호하는 편이다.
png 파일은 색상 변경이 되지 않기 때문에 active되어 색상이 변경된 파일과 원본 파일 2개의 파일이 필요하다.
하지만 svg는 색상 변경이 가능하기 때문에 png파일과는 달리 1개의 파일로 컨트롤이 가능하다.

그래서 react-native에서 svg 파일을 사용하기 위한 설정을 추가해주었다.

 

1. svg 라이브러리 설치

https://github.com/software-mansion/react-native-svg

 

GitHub - software-mansion/react-native-svg: SVG library for React Native, React Native Web, and plain React web projects.

SVG library for React Native, React Native Web, and plain React web projects. - software-mansion/react-native-svg

github.com

npm install react-native-svg
cd ios && pod install

react-native-svg는 <Svg /><G /><Path /> 등 거의 모든 SVG 관련 컴포넌트를 제공한다.
하지만, SVG 파일 자체를 
import 할 수 있게 해주지는 않기 때문에 다른 라이브러리를 또 설치해야 한다.

 

2. react-native-svg-transformer 라이브러리 설치

이 라이브러리는 svg를 react component처럼 사용할 수 있도록 도와준다.

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

 

GitHub - kristerkari/react-native-svg-transformer: Import SVG files in your React Native project the same way that you would in

Import SVG files in your React Native project the same way that you would in a Web application. - kristerkari/react-native-svg-transformer

github.com

npm install --save-dev react-native-svg-transformer

 

3. metro.config.js 변경

const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
const defaultConfig = getDefaultConfig(__dirname);
const {assetExts, sourceExts} = defaultConfig.resolver;

/**
 * Metro configuration
 * https://reactnative.dev/docs/metro
 *
 * @type {import('metro-config').MetroConfig}
 */
const config = {
  transformer: {
    babelTransformerPath: require.resolve('react-native-svg-transformer'),
  },
  resolver: {
    assetExts: assetExts.filter(ext => ext !== 'svg'),
    sourceExts: [...sourceExts, 'svg'],
  },
};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);

 

4. svg import하여 사용

import React from 'react';
import {StyleSheet, TouchableOpacity, View} from 'react-native';
import HomeSvg from '../assets/icons/home.svg'; 
import SearchSvg from '../assets/icons/search.svg';
import PlusSvg from '../assets/icons/plus.svg';
import PlaySvg from '../assets/icons/play.svg';
import AccountSvg from '../assets/icons/account.svg';

const BottomTab = ({navigation, state}) => {
  // 탭 클릭 이벤트
  const moveTab = name => {
    navigation.navigate(name);
  };

  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={() => moveTab('Home')}>
        <HomeSvg
          width={36}
          height={36}
          color={state.index === 0 ? '#555' : '#ddd'}
        />
      </TouchableOpacity>
      <TouchableOpacity onPress={() => moveTab('Search')}>
        <SearchSvg
          width={36}
          height={36}
          color={state.index === 1 ? '#555' : '#ddd'}
        />
      </TouchableOpacity>
      <TouchableOpacity onPress={() => moveTab('Plus')}>
        <PlusSvg
          width={36}
          height={36}
          color={state.index === 2 ? '#555' : '#ddd'}
        />
      </TouchableOpacity>
      <TouchableOpacity onPress={() => moveTab('Play')}>
        <PlaySvg
          width={36}
          height={36}
          color={state.index === 3 ? '#555' : '#ddd'}
        />
      </TouchableOpacity>
      <TouchableOpacity onPress={() => moveTab('Account')}>
        <AccountSvg
          width={36}
          height={36}
          color={state.index === 4 ? '#555' : '#ddd'}
        />
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    paddingHorizontal: 24,
    paddingTop: 12,
    paddingBottom: 16,
    borderTopWidth: 0.5,
    borderColor: '#ddd',
    backgroundColor: '#fff',
  },
});

export default BottomTab;

import한 svg컴포넌트에 color를 설정해주면 색상이 변경된다.
만약 변경이 안된다면 해당 svg 파일의 path의 fill을 확인해봐야 한다.

<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor" d="M12 4C13.0609 4 14.0783 4.42143 14.8284 5.17157C15.5786 5.92172 16 6.93913 16 8C16 9.06087 15.5786 10.0783 14.8284 10.8284C14.0783 11.5786 13.0609 12 12 12C10.9391 12 9.92172 11.5786 9.17157 10.8284C8.42143 10.0783 8 9.06087 8 8C8 6.93913 8.42143 5.92172 9.17157 5.17157C9.92172 4.42143 10.9391 4 12 4ZM12 6C11.4696 6 10.9609 6.21071 10.5858 6.58579C10.2107 6.96086 10 7.46957 10 8C10 8.53043 10.2107 9.03914 10.5858 9.41421C10.9609 9.78929 11.4696 10 12 10C12.5304 10 13.0391 9.78929 13.4142 9.41421C13.7893 9.03914 14 8.53043 14 8C14 7.46957 13.7893 6.96086 13.4142 6.58579C13.0391 6.21071 12.5304 6 12 6ZM12 13C14.67 13 20 14.33 20 17V20H4V17C4 14.33 9.33 13 12 13ZM12 14.9C9.03 14.9 5.9 16.36 5.9 17V18.1H18.1V17C18.1 16.36 14.97 14.9 12 14.9Z" />
</svg>

fill의 값이 currentColor로 되어있어야 적용된다.
내가 가져온 svg들은 보통 다 fill이 currentColor로 지정되어 있었다.
fill을 currentColor로 바꿔주니 색상 변경이 잘 적용되었다.

'🖥️ Frontend > ReactNative' 카테고리의 다른 글

[React Native] ios font 적용 방법  (0) 2024.07.12