🧭 はじめに:画像カルーセルの「あるある」と現場の課題
Webサイトやアプリを作っていると、画像スライダーやカルーセルを入れる場面はよくあります。例えば以下のような場面です:
- トップページのヒーローバナー
- ECサイトの商品ギャラリー
- LPのレビューセクション
一見シンプルに見えるこの機能、実装に入ると実は意外と面倒。「自動再生するけどホバーで止めたい」「レスポンシブ対応が大変」「スワイプ対応したい」「再レンダリングで壊れる」など、現場での苦労話が絶えません。
今回は、React + Tailwind CSS + TypeScriptで、軽量かつ拡張しやすい画像カルーセルをゼロから作り上げていきます。
🔍 技術スタックと仕組みの概要
使用技術
技術 | 用途 |
---|---|
React | UI構築 |
TypeScript | 型安全な実装 |
Tailwind CSS | スタイリング |
Framer Motion(任意) | アニメーション(拡張編) |
機能仕様(今回作るもの)
- 画像を横スライド表示
- 自動スライド(インターバル設定可)
- 左右ボタンで手動切替
- ホバーで自動再生停止
- レスポンシブ対応
- 任意:スワイプ操作(モバイル向け)
💻 実装ステップ:1から組む画像スライダー
まずは、最小構成の画像カルーセルを作っていきます。
① コンポーネント構成
ImageSlider/
├── ImageSlider.tsx
└── images.ts
② デモ用画像リスト images.ts
export const images = [
"/images/img1.jpg",
"/images/img2.jpg",
"/images/img3.jpg",
];
③ メインコンポーネント ImageSlider.tsx
import { useState, useEffect } from "react";
import { images } from "./images";
const ImageSlider = () => {
const [current, setCurrent] = useState(0);
const length = images.length;
useEffect(() => {
const timer = setInterval(() => {
setCurrent((prev) => (prev + 1) % length);
}, 3000);
return () => clearInterval(timer);
}, [length]);
return (
<div className="relative w-full h-64 overflow-hidden">
<div className="flex transition-transform duration-700 ease-in-out" style={{ transform: `translateX(-${current * 100}%)` }}>
{images.map((src, index) => (
<img
key={index}
src={src}
className="w-full object-cover flex-shrink-0"
alt={`slide-${index}`}
/>
))}
</div>
<button
onClick={() => setCurrent((current - 1 + length) % length)}
className="absolute left-2 top-1/2 -translate-y-1/2 bg-white/70 p-2 rounded-full"
>
◀
</button>
<button
onClick={() => setCurrent((current + 1) % length)}
className="absolute right-2 top-1/2 -translate-y-1/2 bg-white/70 p-2 rounded-full"
>
▶
</button>
</div>
);
};
export default ImageSlider;
💡 実務Tips:よくある落とし穴とその回避法
☠️ 落とし穴1:自動再生が止まらない/二重実行
解決法:useEffect
でclearInterval
を忘れずに。
☠️ 落とし穴2:画像サイズが揃っていないとレイアウトが崩壊
解決法:object-cover
と親要素に overflow-hidden
をセット。
☠️ 落とし穴3:スマホでスワイプしても動かない
解決法:react-swipeable
などのライブラリを導入 or touchイベントを自前で実装。
🚀 応用・発展:もっと高度なカルーセルを作りたい人へ
🔁 自動再生に「ホバーで一時停止」機能を追加
onMouseEnter={() => clearInterval(timer)}
onMouseLeave={() => startInterval()}
📱 スワイプ対応:react-swipeable
の導入
npm install react-swipeable
import { useSwipeable } from "react-swipeable";
const handlers = useSwipeable({
onSwipedLeft: () => setCurrent((current + 1) % length),
onSwipedRight: () => setCurrent((current - 1 + length) % length),
});
✨ アニメーション追加:Framer Motionでぬるっと動かす
<motion.div
animate={{ x: -current * 100 + "%" }}
transition={{ duration: 0.5 }}
className="flex"
>
🧾 まとめ:導入のしやすさと拡張性のバランスが鍵
観点 | 内容 |
---|---|
✅ メリット | 軽量、自由度が高い、Tailwindで簡単デザイン |
⚠️ デメリット | 機能追加には多少のJS力が必要 |
🌱 今後の応用 | 動画スライダー、サムネイル付き、API連携による動的画像 |
🌟 さいごに:あなたも画像カルーセルを作ってみよう!
自作することで理解が深まり、業務での応用力も高まります。この記事をベースに、自社プロダクトに最適なスライダーを育ててみてください!
👉 次回:「通貨換算アプリ(為替API)」