ハイパーマッスルエンジニア

Vim、ShellScriptについてよく書く

Reactのアニメーションライブラリ「framer motion」がすこぶるいい

 
Reactでアニメーションコンポーネントをサクッと作れるライブラリ「framer motion」。
非常に簡単にアニメーションをつけることができたので伝えたい。 www.framer.com

インストール

yarn add framer-motion

かんたんアニメーション

こんなdiv要素を用意して

<div style={{ width: '100px', height: '100px', background: 'blue' }}></div>

motion.divにしてanimateを追加して画面をリロードする

+ import { motion } from 'framer-motion'

+ <motion.div 
  style={{ width: '100px', height: '100px', background: 'blue' }}
+  animate={{ x: 200 }}>
+ </motion.div>

ホバーしたらアニメーション発火

<motion.div 
  style={{ width: '100px', height: '100px', background: 'blue' }}
  whileHover={{ scale: 1.5 }}
</motion.div>

whileHoverwhileTapにしたらクリックで発火するようになる。 他にも指定可能なオプションが結構ある。

Gestures | Framer for Developers

ほとんどすべての要素にアニメーションがつけれる

div以外でもimgp, svgなんかにも同様にアニメーションがつけられます。
他のライブラリと組み合わせることができるので非常に便利です。

例えばグラフライブラリのrechartsと組み合わせるとこんな感じ。

rechartsの「Treemap」のラベルにアニメーションを付与しています。もともとのTreemapではホバーした際は何も起きないのですが、svgで構成されているラベルを<motion.text>に変更することでアニメーションを付与しています。
Treemapのcontentにカスタムコンポーネントを指定し、svgのテキストにアニメーションを付与する形です。

<Treemap
  data={data}
  dataKey="size"
  stroke="#fff"
  content={<TreemapItem />}
>


//  TreemapItem.tsx
export const TreemapItem = (props) => {
  const { depth, x, y, width, height, index, name } = props

  return (
    <g>
      <rect
        x={x}
        y={y}
        width={width}
        height={height}
        fill={'rgba(255,255,255,0)'}
        stroke="#fff"
        strokeWidth={2 / (depth + 1e-10)}
        strokeOpacity={1 / (depth + 1e-10)}
        style={{ cursor: 'pointer' }}
      />
        <motion.text
          animate={{ scale: 2.0, fontWeight: 700 }}
          ...
        </motion.text>

実際のソース

動作を見たい方は下記から試せます。
https://app.rasukarusan.com/sheet/2021

このように他のライブラリと掛け合わせることが簡単にできるので、ちょっとした動きをつけたいときに良いですね。

終わりに

framer-motionでは3Dコンテンツを扱える「three.js」のアニメーションにも対応しているみたいです。
react-springと迷いましたが、パッと見のドキュメントのみやすさはframer-motionのほうが見やすいなと思いました。ドキュメントの分量も適量でした。