ReactでSVGに動的に色を付ける

ブラウザで簡単に塗り絵が出来たら楽しそうだなあと思って、アプリを作ってみました。

アイコンの色違い作るよ!

そこで svg に動的に色付けするのはどうやるんだろうな、と思って調べたことまとめ。

svg を用意する

丸や四角などの描画は svg のインラインでどうにかなるので置いておく。

その他のイラスト部分は、jpg とか png から svg にできる Web サービスがあるので、いい感じの変換ができたものを使う。 サービスによって、中身が img の svg ファイルが焼きあがることがあるので、いろいろ試すのがいいかも。

(中身が img で書かれていたら、それはただのイメージファイルなので色の変更とかできない)

取得出来たら、svg ファイル内のカラー設定を削除する。fill=#000000 とかがあれば、fill ごと削除する。

カラーピッカーをインストール

作ろうと思ったけど、あまり興味がないので探してみました。

ざっくり見て回ったところ、react-input-colorがよさそうだったので

yarn add react-input-color

として追加する。

コンポーネント実装部分

ヘッドホンに色をつけてみる。

ここで大事なのは、headPhone.svg を ReactComponent として読み込んでいること。そこさえうまくいけば、あとは fill={}に色を渡せばよい。

drawing.js
import React from 'react'
import InputColor from 'react-input-color'
import { ReactComponent as HeadPhone } from './headPhone.svg'

const Drawing = () => {
  const [colorHeadPhone, setColorHeadPhone] = React.useState({})

  return (
    <div className="boxContainer">
      <div className="box" style={{ width: 280 }}>
        <div
          className="svgImage"
          style={{
            position: 'absolute',
            zIndex: 100,
          }}
        >
          <HeadPhone height="200" width="200" fill={colorHeadPhone.rgba} />
        </div>
      </div>

      {/* ハンドリング */}
      <div className="box">
        <div style={{ position: 'relative' }}>
          <span className="colorTitle">HeadPhone</span>
          <InputColor
            initialValue="#000000"
            onChange={setColorHeadPhone}
            placement="right"
            style={{ height: 38, padding: 0 }}
          ></InputColor>
          <div className="colorNameContainer">
            <div className="colorName">{colorHeadPhone.rgba}</div>
            <div className="colorName">{colorHeadPhone.hex}</div>
          </div>
        </div>
      </div>
    </div>
  )
}

全体像

参考