0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React + Tailwindでテキストアニメーションを実装してみた

Last updated at Posted at 2025-07-02

こんにちは、今回はReactとTailwind CSSを使って、テキストが1文字ずつアニメーションしながら表示されるUIを実装してみました。

完成イメージはこんな感じです👇

CleanShot 2025-07-03 at 02.50.23.gif

実装コード

"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 が有名ですが、これぐらいであればわざわざパッケージを入れるよりも保守の観点から自作してもいいかなと思い試してみました。

ぜひ自分のポートフォリオやランディングページなどに使ってみてください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?