こんにちは。データアナリティクス事業本部 サービスソリューション部の北川です。
今回は、Framer Motionで提供されているhooksを使用してみたいと思います。
Framer
Framerとは、コードベースのUIデザインツールになります。Framer側、React側それぞれでデザインをインポートし、取り込めるのが特徴です。
以下の記事がわかりやすいです。
Framer Motion
Framer Motionは、Framerで作成したコンポーネントに対応したReactアニメーションライブラリです。
基本的な動作については、こちらの記事で紹介されています。
Framer Motionにはコンポーネントに渡すprops以外にも、面白いhooksを提供しています。
今回は以下の3つを試してみました。
- useCycle
- useReducedMotion
- useDragControls
使用準備
Framer Motionをインストールします
yarn add framer-motion
// または
npm install framer-motion
useCycle
メソッドが発火するたびに、引数に渡した値を循環させます。 以下の例では、cycleX()が呼び出されるたびに値が0,50,100,150と変化していき、0に戻ります。
import { motion, useCycle } from "framer-motion";
const Sample = () => {
const [x, cycleX] = useCycle(0, 50, 100, 150);
return (
<motion.div
style={{ width: "200px", height: "200px", background: "skyblue" }}
animate={{ x: x }}
onClick={() => cycleX()}
/>
);
};
export default Sample;
動作確認
useReducedMotion
アニメーションによる影響を抑えたい場合に使用し、「動きを減らす」設定を行います。アニメーションにより、目眩などを起こすユーザーに対応するhooksです。
import { motion, useReducedMotion } from "framer-motion";
import { FC, useState } from "react";
const Box: FC<{ isOpen: boolean }> = ({ isOpen }) => {
const shouldReduceMotion = useReducedMotion();
const closedX = shouldReduceMotion ? 0 : "-100%";
return (
<>
<motion.div
style={{ width: "200px", height: "200px", background: "skyblue" }}
animate={{
opacity: isOpen ? 1 : 0,
x: isOpen ? 0 : closedX,
}}
/>
</>
);
};
const Sample = () => {
const [isOpen, setIsOpen] = useState(true);
return (
<>
<Box isOpen={isOpen} />
<button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? "close" : "open"}
</button>
</>
);
};
export default Sample;
falseの場合
trueの場合
useDragControls
ポインターイベントの実装を可能にします。useDragControls()を使用し、これをドラッグ可能なコンポーネントに渡すことで使用できます。同じくFramer Motionのstart()を使用し、カーソルの移動に対して、メソッドが発火されるよう指定します。
import { motion, useDragControls } from "framer-motion";
import { MouseEvent } from "react";
const Sample = () => {
const dragControls = useDragControls();
const startDrag = (event: MouseEvent) => {
dragControls.start(event, { snapToCursor: true });
};
return (
<>
<div
style={{ width: "100%", height: "200px"}}
onPointerDown={startDrag}
/>
<motion.div
style={{ width: "200px", height: "200px", background: "skyblue" }}
drag="x"
dragControls={dragControls}
/>
</>
);
};
export default Sample;
まとめ
今回は、Framer Motionのhooksを使用して、アニメーションを実装することができました。 Framer Motionには他にも面白い機能がありそうなので、今後も試してみたいと思います。
ではまた。