Framer Motionは、本番環境に対応したReact用のモーションライブラリです。構文は宣言的で、複雑なアニメーションのコードも簡潔に書けます。つまり、コードベースが読みやすく、保守しやすいということです。
Framer Motionは、つぎのようにインストールしてください。
npm install framer-motion
アニメーションの基本
宣言的な構文でアニメーションのコードを書くために、中心的な役割を果たすのがmotion
コンポーネントです。DOM要素として扱え、アニメーションの機能が拡張されます。
たとえば、アニメーションさせたい要素が<div />
であれば、motion
コンポーネントをimport
したうえで、つぎのように<motion.div />
に差し替えてください。
import { motion } from 'framer-motion';
export default function App() {
return (
// <div />
<motion.div />
);
}
motion
コンポーネントにアニメーションを加えるのはanimate
プロパティです。値をオブジェクトでつぎのように定めれば、コンポーネントが表示されると、サイズ(scale
)は半分になりつつ、透明(opacity
)に変化します。
import { motion } from 'framer-motion';
export default function App() {
return (
<motion.div
animate={{ opacity: 0, scale: 0.5 }}
/>
);
}
アニメーションが速すぎるかもしれません。どう変化させるかを調整するのは、transition
プロパティです(「Transition」参照)。duration
でアニメーションにかける秒数を定めましょう。
export default function App() {
return (
<motion.div
animate={{ opacity: 0, scale: 0.5 }}
transition={{ duration: 1 }}
/>
);
}
initial
プロパティを用いれば、アニメーションの初期値が決められます。DOM(<motion.div />
)のもともとの設定と異なる初期値から、本来の表示に戻るよう変化させる例がつぎのコードです(サンプル001)。透明な(opacity
)要素が左(x
)から姿を表し、拡大(scale
)しながら、もともとの設定に落ち着きます。
export default function App() {
return (
<motion.div
initial={{ opacity: 0, scale: 0, x: -400 }}
// animate={{ opacity: 0, scale: 0.5 }}
animate={{ opacity: 1, scale: 1, x: 0 }}
transition={{ duration: 1 }}
/>
);
}
サンプル001■React + TypeScript: Framer Motion Examples 01
https://codesandbox.io/s/react-typescript-framer-motion-examples-01-gfy2zq
キーフレーム
animate
に与えるオブジェクトプロパティの値を配列で渡して、段階的に変化させるのがキーフレームです。以下のコード例は、つぎの3つのプロパティを開始値から終了値に変化させます。
プロパティ | 開始値 | 終了値 |
---|---|---|
scale | 2 | 1 |
rotate | 180 | 0 |
borderRadius | 50% | 0% |
export default function App() {
return (
<motion.div
animate={{
scale: [2, 1],
rotate: [180, 0],
borderRadius: ['50%', '0%']
}}
transition={{
duration: 2
}}
/>
);
}
プロパティ値(キーフレーム)は、配列要素にいくつ加えても構いません。そうすると、細かなアニメーションが定められるでしょう。
export default function App() {
return (
<motion.div
animate={{
// scale: [2, 1],
scale: [1, 2, 2, 1, 1],
// rotate: [180, 0],
rotate: [0, 0, 180, 180, 0],
// borderRadius: ['50%', '0%']
borderRadius: ['0%', '0%', '50%', '50%', '0%']
}}
/>
);
}
デフォルトでは、キーフレーム間のアニメーション時間は均等です。transition
のtimes
で、この間隔が調整できます(サンプル002)。値は0が開始、1で終了する小数値です。さらに、ease
はイージング関数、repeat
が繰り返し回数、repeatDelay
でつぎの繰り返しまでの溜め(待ち秒数)を定められます。
export default function App() {
return (
<motion.div
transition={{
duration: 2,
ease: 'easeInOut',
times: [0, 0.2, 0.5, 0.8, 1],
repeat: Infinity,
repeatDelay: 1
}}
/>
);
}
サンプル002■React + TypeScript: Framer Motion Examples 02
https://codesandbox.io/s/react-typescript-framer-motion-examples-02-8k925n
ジェスチャーアニメーション
ジェスチャーは、アクティブになるとその間コンポーネントの視覚的な状態にアニメーションを加えるつぎのようなヘルパープロパティです。
つぎのコード例では、whileHover
とwhileTap
を用いました。値のアニメーションの定め方は、animate
と同じです。以下のサンプル003で、コードと動きを見比べていただくのが手っ取り早いでしょう。
export default function App() {
return (
<div>
<motion.div whileHover={{ scale: 1.2 }} whileTap={{ scale: 0.8 }} />
</div>
);
}
サンプル003■React + TypeScript: Framer Motion Examples 03
https://codesandbox.io/s/react-typescript-framer-motion-examples-03-dfgpq4
ドラッグ
ドラッグのジェスチャーアニメーションは、drag
プロパティを加えるだけです。ドラッグ領域の上(top
)下(bottom
)左(left
)右(right
)の範囲は、dragConstraints
プロパティで決められます。
export const Example: FC = () => {
return (
<>
<motion.div
drag
dragConstraints={{
top: -50,
left: -50,
right: 50,
bottom: 50
}}
/>
</>
);
};
ドラッグ領域を数値でなく、DOM要素の矩形で定めたい場合もあるでしょう。そのときは、範囲にしたいDOM要素にref
を与えてください。dragConstraints
プロパティの値とするのはそのref
オブジェクトです(サンプル004)。
export const Example: FC = () => {
const constraintsRef = useRef<HTMLDivElement>(null);
return (
<>
<motion.div ref={constraintsRef} />
{/* <motion.div
drag
dragConstraints={{
top: -50,
left: -50,
right: 50,
bottom: 50
}}
/> */}
<motion.div drag dragConstraints={constraintsRef} />
</>
);
};
サンプル004■React + TypeScript: Framer Motion Examples 04
https://codesandbox.io/s/react-typescript-framer-motion-examples-04-3rnffz
Framer Motionの基本的な使い方について、作例のコードを書き進めながらご説明しました。作例は公式サイトの「Examples」から拾いつつ、細かな手を加えています。
「Examples」には、本稿で説明しきれなかったサンプルがまだ多くあるので、興味のある方はご覧になるとよいでしょう。もっとも、コードの説明はほぼなく、サンプルにも不要なモジュールやコードが残っていたりするのでご注意ください。
この記事が好評でしたら、続編も考えます。