🌊
framer-motionでスクロールをリッチに
はじめに
framer-motionはアニメーションを簡単につけることができるライブラリです。
使い方としてはこのようにタブの頭にmotion.を付け、プロップスに各値を渡します。<motion.div animate={{ x: 100 }} />
基本的にinitialにアニメーションの初期位置、animateに終了位置、transitionに動き方を書きます。
<motion.div
initial={{ y: 100, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{
duration: 1,
delay: 0.5,
stiffness: 130 }}
/>
これだけでアニメーションができるのですごく簡単ですね。
調べてみるとスクロールでふわっと要素を表示したり、みた事あるwebアニメーションも簡単にできるみたいなので、やってみました。
作ってみた画面
コード
const cakeList = [
{
id: 1,
name: "ショートケーキ",
path: "cake1",
discription:
"割愛",
},
{
id: 2,
name: "チョコレートケーキ",
path: "cake2",
discription:
"割愛",
},
{
id: 3,
name: "ガトーショコラ",
path: "cake3",
discription:
"割愛",
},
{
id: 4,
name: "チーズケーキ",
path: "cake4",
discription:
"割愛",
},
];
const { scrollYProgress } = useScroll();
return (
<>
<motion.div
style={{ scaleX: scrollYProgress }}
className="fixed top-0 left-0 right-0 h-5 bg-red-500 origin-left"
/>
<div className="flex justify-center items-center min-h-screen bg-gray-100">
<div className="bg-white p-8 rounded-lg shadow-lg max-w-sm my-20">
<h1 className="text-2xl font-bold mb-6 text-center bg-red-200 p-5 rounded-lg">
色んなケーキ
</h1>
<ul>
{cakeList.map((cake) => {
return (
<motion.li
viewport={{ once: true }}
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
transition={{ delay: 1 }}
className="my-20"
>
<h1 className="text-2xl font-bold mb-6">{cake.name}</h1>
<img
src={`/src/assets/image/${cake.path}.png`}
className="w-[700px]"
/>
<p className="text-lg">{cake.discription}</p>
</motion.li>
);
})}
</ul>
</div>
</div>
</>
);
スクロール地点でふわっと表示させるところはmotion.liタグの中に書いています。
whileInViewで画面内に表示された時の挙動を指定して、viewportで一度だけそのフェードインが実行されるようにします。4行で実装できました。
上のスクロールに合わせて伸びるバーはframer-motionのカスタムフックuseScrollを使っています。
useScrollはスクロールの絶対座標scrollX, Yとプログレスの進行割合をscrollXProgress, scrollYProgressで4つの値を返しましす。
今回はy座標の進行割合だけ確認したいのでscrollYProgressだけ取り出しました。
framer-motionは初めて触ったのですが、感覚的に非常に分かりやすかったです。
参考にさせていただいた記事
NCDC株式会社( ncdc.co.jp/ )のエンジニアチームです。 募集中のエンジニアのポジションや、採用している技術スタックの紹介などはこちら( github.com/ncdcdev/recruitment )をご覧ください! ※エンジニア以外も記事を投稿することがあります
Discussion