エラー出まくったり情報が古いのばっかりだ
React Nativeでsvgを使う方法が色々散見していてエラー出たりしてる人多いと思いますが、個人的なやり方を記載します。
あと、今はダークモード対応とかで動的に色を変更したい時もあると思うので、それも記載します。
環境は下記
react-native-cli: 2.0.1
react-native: 0.63.4
とりあえず react-native-svg-transformer を使うまで
react-native-svg-uriを使うという記事とかも見かけましたが、私は「react-native-svg-transformer」を使い続けています。
使い方は、git見れば分かるんですが意外と公式見ずに英語分からない(?)人もいるので、記載します。
(というか、react-native-svg-uriまともに動いたことあったっけなぁ…)
yarn add react-native-svg
npx pod-install
yarn add --dev react-native-svg-transformer
App.jsのあるルートに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をimportしてJSX上でサイズ指定してあげれば使えるはず。
import Logo from '../img/logo.svg'
/*~略~*/
<Logo width={100} height={100} />
動的に色を変更する場合 -その1 (単色の場合)
該当の、svgのfillの部分を「currentColor」に変える。(HTMLでSVGの色を変更する方法と同じですね。)
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect width="300" height="100" fill="#f00"/>
</svg>
これを下記にする
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect width="300" height="100" fill="currentColor"/>
</svg>
で、JSX上でstyleで設定する
<Logo width={100} height={100} style={{color:'#ccc'}} />
動的に色を変更する場合 -その2 (複数の色、ただし5色まで)
これもreact-native-svg-transformerの公式に書いてあるけどSVGRを使う。
- App.jsのあるルートに.svgrrcのファイルを作る(隠しファイル面倒だねー)
- SVGファイルのfillの値を「#000,#f00,#ff0,#ff1,#f11」の5色のどれかに変更する。
- .svgrrcを以下のように書く
{
"replaceAttrValues": {
"#000": "{props.hoge}",
"#00f": "{props.foo}",
"#ff0": "{props.bar}",
}
}
- JSXで
<Logo width="100" height="100" hoge={"#f00"} />
SVGRでの問題点
なんか該当svgのfillが#000じゃないと動かないとか、動かないとかあった…
結論、svgの色の置き換えはrgbの3桁のみで、置き換え可能な文字列は
RGB |
---|
#000 |
#f00 |
#ff0 |
#ff1 |
#f11 |
この5つぐらいしかできなかった、websafeカラーの0,3,6,9,cの組み合わせは殆どダメだった。(#f0fがダメとか、#0ffがダメとか納得いかねー)
まぁ、色数が多いものは動的に変えるなちゅー話だろうなぁ…
以下はダメだったもの
# fff
# 00f
# ccc
# 222-999
# 11f
# 1f1
# 1ff
# f01
# f1f
# f12
# 0ff
# f01
# ff0
# ff1
# f1f
# 3ff
# 321
# f03
# 90f
# 100
# 101
まぁ、5色以上変える場合は、そもそも別のSVG作れちゅー話なんだろうけど、SVGRの仕様的には6桁のRGB値でも変更できるはずだし、正規表現まで対応できているはずなのになぁ…