「動き」のあるタイトル要素は、ホームページの雰囲気を大きく変えることができます。この記事では、文字が1文字ずつ現れるアニメーションの実装方法を分かりやすく解説します。

今回の記事で分かること
文字が1文字ずつ現れるアニメーションの実装方法がわかります。

完成デモの紹介

まずはデモをご覧ください。

See the Pen テキストを1文字ずつ出現させるアニメーション by はなはな氏 (@wxftomuu-the-selector) on CodePen.

HTML

今回のサンプルでは、jQueryとCSSを使用して、テキストを1文字ずつ表示するアニメーションを実装しています。
任意の要素にクラス名 .eachTextAnime を付与するだけで、簡単にアニメーション効果を適用できます。

<!-- jQuery 読み込み -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

<h3>テキストを1文字ずつ出現させるアニメーション</h3>

<div class="title_area">
  <!-- 英語タイトル(.eachTextAnime を付与することでアニメーション適用) -->
  <div class="en eachTextAnime"><span class="yellow">R</span>ANKING</div>
  
  <!-- 日本語タイトル(同様にアニメーション適用) -->
  <div class="ja eachTextAnime">人気ランキング</div>
</div>
<p class="eachTextAnime">要素は任意で構いません。</p>
<p>divでもpでもspanでも<span class="eachTextAnime">.eachTextAnime</span>を付与するだけでアニメーションが適用されます。</p>

CSS

続いて、文字に適用するCSSをご紹介します。
.eachTextAnime を付与した要素内のテキストは、後述のスクリプトで1文字ずつ に分割され、opacity と transform を用いてフェードイン+軽い動きを与えています。.appeartext クラスが付与されると、各文字のアニメーションが順番に実行されます。

/* =========================
   コンテンツ全体の基本スタイル
========================= */
/* 
この部分は、アコーディオンを適用するための
サンプルレイアウト(見た目)のスタイルです。
実際のサイトに合わせて、自由にカスタマイズしてください。
*/
body {
  background: #1a8093;
  color: #fff;
}
h3, p {
  text-align: center;
}

/* タイトルエリアのスタイル */
/* 
実際のサイトに合わせて、自由にカスタマイズしてください。
*/
.title_area .en {
  font-family: Arial, sans-serif;
  font-weight: bold;
  font-size: 3rem;
  line-height: 3rem;
}
.title_area .ja {
  font-weight: bold;
  font-size: 1.5rem;
}
.yellow {
  color: #FFD900;
}

/* 1文字ずつ表示するアニメーション設定
---------------------------*/
.eachTextAnime {
  display: flex;                  /* 子要素(文字)を横並びに */
  justify-content: center;        /* 中央配置 */
}
.eachTextAnime span {
  opacity: 0;                     /* 初期状態は非表示 */
}
.eachTextAnime.appeartext span {
  animation: text_anime_on 1s ease-in-out forwards;  /* appeartext クラスが付いたらアニメーションを実行 */
}

/* アニメーションの動き定義
---------------------------*/
@keyframes text_anime_on {
  0% {
    opacity: 0;                   /* 完全に非表示 */
    transform: translate3d(0, 0, 0); /* 位置はそのまま */
  }
  50% {
    opacity: 0;                   /* 中盤まで非表示 */
    transform: translate3d(0, 0, 0);
  }
  70% {
    opacity: 0.5;                 /* 少し表示しながら */
    transform: translate3d(0, -10px, 0); /* 上にふわっと移動 */
  }
  100% {
    opacity: 1;                   /* 完全表示 */
    transform: translate3d(0, 0, 0); /* 元の位置に戻す */
  }
}

JS

最後に、文字を1文字ずつ出現させるための JavaScript の処理です。
要素が画面内に入ったタイミングでアニメーションが開始される仕組みになっています。
.eachTextAnime クラスを持つ要素の文字列を に分割し、1文字ずつアニメーションの遅延(animation-delay) を設定することで、順番に文字がフェードインするようになっています。

// テキストを1文字ずつ出現させるためのスクリプト
// ----------------------------------

// 要素が画面内に入ったら .appeartext を付与する関数
function EachTextAnimeControl() {
  $('.eachTextAnime').each(function () {
    var elemPos = $(this).offset().top - 50; // 要素の位置(少し上に余裕を持たせる)
    var scroll = $(window).scrollTop();      // 現在のスクロール位置
    var windowHeight = $(window).height();   // 画面の高さ

    // 要素が画面に入ったら .appeartext を追加、外れたら削除
    if (scroll >= elemPos - windowHeight) {
      $(this).addClass("appeartext");
    } else {
      $(this).removeClass("appeartext");
    }
  });
}

// テキストを <span> で分割し、遅延アニメーションを設定する関数
function TextAnimeLoad() {
  var element = $(".eachTextAnime");
  element.each(function () {
    var html = $(this).html();   // 元のテキストを取得
    var textbox = "";            // 新しいHTMLを組み立てる用
    var index = 0;               // アニメーション遅延のカウンタ

    // <span> が含まれていても分割できるように正規表現で処理
    var regex = /(<span class="[^"]*">.*?<\/span>|[\s\S])/g;
    var parts = html.match(regex);

    parts.forEach(function (part) {
      var match = part.match(/<span class="([^"]*)">.*<\/span>/);
      if (match) {
        // spanタグ付きの文字(例: <span class="yellow">R</span>)
        var spanClass = match[1];                   // span のクラス名を保持
        var text = part.replace(/<[^>]+>/g, '');    // タグを除去して中身の文字を取得
        text.split('').forEach(function (t) {
          if (t !== " ") { // 空白は処理しない
            // index を使ってアニメーション遅延を設定
            if (index < 10) {
              textbox += '<span class="' + spanClass + '" style="animation-delay:.' + index + 's;">' + t + '</span>';
            } else {
              var n = index / 10;
              textbox += '<span class="' + spanClass + '" style="animation-delay:' + n + 's;">' + t + '</span>';
            }
            index++;
          } else {
            textbox += ' '; // 空白はそのまま残す
          }
        });
      } else {
        // 通常の文字(spanで囲まれていないもの)
        if (part.trim() !== "") {
          if (index < 10) {
            textbox += '<span style="animation-delay:.' + index + 's;">' + part + '</span>';
          } else {
            var n = index / 10;
            textbox += '<span style="animation-delay:' + n + 's;">' + part + '</span>';
          }
          index++;
        } else {
          // 空白は &nbsp に置き換え
          textbox += '<span>&nbsp</span>';
        }
      }
    });

    $(this).html(textbox); // 分割したHTMLを要素に反映
  });

  // ページ読み込み時にもチェック
  EachTextAnimeControl();
}

// ページが読み込まれたらすぐに実行
// ----------------------------------
$(window).on('load', function () {
  TextAnimeLoad();
});

// スクロール時にアニメーションを制御
// ----------------------------------
$(window).scroll(function () {
  EachTextAnimeControl();
});

まとめ

今回ご紹介したサンプルでは、HTML・CSS・JavaScript を組み合わせて、テキストを1文字ずつアニメーション表示する方法を解説しました。見出しやタイトルを際立たせたいときにぜひ活用してみてください。

なお、弊社では「サイトの更新まで手が回らない…」という方向けに、更新作業の代行や技術的なサポートも承っております。「同じように実装したけれどうまく動かない」などお困りの際は、お気軽にご相談ください。

少しでもこの記事がお役に立てれば幸いです。最後までお読みいただき、ありがとうございました。

おすすめの記事