はじめに
サイト制作で記事のリンク一覧を作成した。
各リンク一覧がviewportに映ったら、サムネイル画像が下から上に表示されるようにしたい。
そのためには、サムネイル画像の上に同じ形の黒い長方形を用意して、
映ったタイミングでそれを上へスライドさせるという実装をする必要があった。
これを Framer Motion
を使って実装する。
Framer Motionとは?
Framer Motion は React 向けのアニメーションライブラリ。
initial
や animate
などの予約語を使うことで、状態ごとにアニメーションを管理できるのがとても便利。
まずはインストール。
npm install framer-motion
実装の概要
やりたいことは次の通り:
- サムネイル画像の上に黒いオーバーレイ(div)を重ねる
-
Framer Motion
で、オーバーレイが下から上にスライドするアニメーションを定義 - そのオーバーレイが viewport に入ったタイミングでアニメーション発火
実装コード(React + Framer Motion)
AnimationLink.tsxというコンポーネントを作成した
これに記事データのpropsを渡して使用している
'use client'
import { motion } from 'framer-motion'
import styles from './articleLink.module.scss'
const overlayVariants = {
hidden: { y: '0%' },
visible: (custom: number) => ({
y: '-100%',
transition: {
delay: custom % 2 === 0 ? 0 : 0.2,
duration: 0.6,
ease: [0.2, 0.34, 0.24, 1],
},
}),
}
type Props = {
id: string
title: string
thumbnail_path: string
custom: number
}
export default function ArticleLink({ id, title, thumbnail_path, custom }: Props) {
return (
<div className={styles.item}>
<div className={styles.imageWrapper}>
<Link href={`/production/${id}`}>
<div
className={styles.thumbnailContainer}
>
<img
src={thumbnail_path}
alt={title}
/>
</div>
</Link>
<motion.div
className={styles.overlay}
variants={overlayVariants}
initial="hidden"
whileInView="visible"
viewport={{ once: true, amount: 0.8 }}
custom={custom}
/>
</div>
<h2 className={styles.title}>{title}</h2>
</div>
)
}
ポイント解説
variants
でアニメーション状態を定義
const overlayVariants = {
hidden: { y: '0%' },
visible: (custom: number) => ({
y: '-100%',
transition: {
delay: custom % 2 === 0 ? 0 : 0.2,
duration: 0.6,
ease: [0.2, 0.34, 0.24, 1],
},
}),
}
このように、状態を「名前付き」で管理できる
hidden → visible
に切り替えることで、要素の動きを制御している
whileInView
でスクロール時の表示検知
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, amount: 0.8 }}
/>
-
initial="hidden"
:初期状態 -
whileInView="visible"
:viewport に 80% 入ったらvisible
状態へ切り替え -
once: true
:一度だけアニメーションする
80%に設定した理由は、少しでもビューポートに映るとすぐアニメーションが開始されてしまうため
おわりに
直感的にアニメーション実装ができたので今後も使っていきたい
備忘録として使用頻度が高そうなものをまとめた
プロパティ名 | カテゴリ | 説明 |
---|---|---|
initial |
基本 | 初期状態のスタイル(アニメーション開始前) |
animate |
基本 | アニメーションの最終(または途中)状態 |
exit |
基本 | コンポーネントが消える時の状態(AnimatePresence と併用) |
transition |
基本 | アニメーションの速度・タイミング設定 |
whileHover |
ジェスチャー | ホバー中の状態に変化させる |
whileTap |
ジェスチャー | クリック/タップ中の状態に変化させる |
whileFocus |
ジェスチャー | フォーカス中の状態(アクセシビリティ対応) |
whileDrag |
ジェスチャー | ドラッグ中の状態に変化させる |
variants |
状態制御 | 状態(初期・アニメ・終了)をまとめて定義できるオブジェクト |
drag |
動作制御 | 要素をドラッグ可能にする(true / x / y ) |