こんにちは、今回はReactとTailwind CSSを使って、テキストが1文字ずつアニメーションしながら表示されるUIを実装してみました。
完成イメージはこんな感じです👇
実装コード
"use client";
import { useEffect, useState } from "react";
export function TextAnimation() {
const [visibleChars, setVisibleChars] = useState(0);
const text = "Hello, World! Welcome to the Text Animation Demo";
const speed = 200;
useEffect(() => {
const timer = setInterval(() => {
setVisibleChars((prev) => {
if (prev < text.length) {
return prev + 1;
}
clearInterval(timer);
return prev;
});
}, speed);
return () => clearInterval(timer);
}, [text.length]);
return (
<h1 className="text-4xl md:text-6xl font-bold text-gray-800 mb-8">
{text.split("").map((char, index) => (
<span
key={index}
className={`inline-block transition-all duration-500 ease-out ${
index < visibleChars
? "opacity-100 scale-100 translate-y-0"
: "opacity-0 scale-50 translate-y-4"
}`}
style={{
transitionDelay: `${index * 100}ms`,
}}
>
{char === " " ? "\u00A0" : char}
</span>
))}
</h1>
);
}
解説
純を追って説明していきます👇
1. useState と useEffect を使って表示文字数をコントロール
const [visibleChars, setVisibleChars] = useState(0);
- 最初は0文字表示された状態(空っぽ)からスタート
- visibleChars という状態を使って、「今、何文字目まで画面に出すか」を制御する
次に、useEffect の中で setInterval を使って、一定間隔で visibleChars を増やしていきます。
const timer = setInterval(() => {
setVisibleChars((prev) => {
if (prev < text.length) {
return prev + 1;
}
clearInterval(timer);
return prev;
});
}, speed);
文字を1文字ずつ分割してアニメーションを設定
{text.split("").map((char, index) => (
<span
key={index}
className={...}
style={{ transitionDelay: `${index * 100}ms` }}
>
{char === " " ? "\u00A0" : char}
</span>
))}
- text.split("") で文字列を1文字ずつに分解する
- map() を使って、1文字ずつ にラップして表示する
- 各文字に
transition-delay
を設定することで、1文字ずつ時間差で表示されるアニメーション
Tailwind CSSでアニメーション制御
各文字の に以下のようなTailwindクラスを条件付きで適用しています。
className={`inline-block transition-all duration-500 ease-out ${
index < visibleChars
? "opacity-100 scale-100 translate-y-0"
: "opacity-0 scale-50 translate-y-4"
}`}
状態 | クラス | 効果 |
---|---|---|
表示前 | opacity-0 scale-50 translate-y-4 |
小さく、下にあり、透明 |
表示対象 | opacity-100 scale-100 translate-y-0 |
通常サイズ、上に移動、透明解除 |
このようにして、「下からふわっとスケールしながら浮かび上がってくる」というアニメーションを表現しています。
まとめ
アニメーションだと framer-motion - npm が有名ですが、これぐらいであればわざわざパッケージを入れるよりも保守の観点から自作してもいいかなと思い試してみました。
ぜひ自分のポートフォリオやランディングページなどに使ってみてください!