jackmiwamiwa devblog

フロントエンドをメインに行ったことをまとめていくサイトになります。

cssとjsを使ってテキストに1文字ずつアニメーションさせる

テキストを1文字ずつアニメーションさせるときに手動でspanを囲わないで行いたいときに

成果物

See the Pen テキストアニメーション by miwa_shuntaro (@miwashutaro0611) on CodePen.

行ったこと

1. HTMLの作成

.txt: テキスト全体
.line: 改行させるためのもの

<p class="txt">
  <span class="line">テキストを</span>
  <span class="line">1文字ずつ</span>
  <span class="line">アニメーションする</span>
</p>

2. jsでテキスト1文字ずつにspanを導入する

function txtSplit() {
  const txtElemAry = document.querySelectorAll('.line') // 要素の取得
  txtElemAry.forEach( item => {
    let txt = '' // HTMLの導入部分初期化
    const textContentAry = item.textContent.split('') // テキスト1文字ずつを配列に格納
    textContentAry.forEach( item2 => {
      txt += item2.replace(/(\S)/g, '<span class="txtInner">$&</span>') // 追加するHTMLなど記載
    })
    item.innerHTML = txt // HTMLの内容を変更
  })
}

実行後のHTML

<p class="txt">
        <span class="line"><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span></span>
        <span class="line"><span class="txtInner">1</span><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span></span>
        <span class="line"><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span><span class="txtInner"></span></span>
</p>

3. animation-delayの秒数を設定

1つずつ順番に出てきて欲しいため、js側で秒数を設定

function addCss() {
  const txtElemAry = document.querySelectorAll('.line') // 要素の取得
  let aryNumner = 0 // 配列の番号(初期値0)
  const defaultTime = 0 // 初期の秒数
  const animeTime = 0.03 // 要素ごとに変化させる秒数
  txtElemAry.forEach( item => {
    [...item.children].forEach( item2 => {
      aryNumner++
      item2.style.animationDelay = `${defaultTime + aryNumner * animeTime}s`
    }) // cssのアニメーションの実行時間の設定
  })
}

cssのアニメーションは以下のように記載する(実行すること・アニメーション時間については共通のため、cssの方に記載)

.txtInner {
  animation-name: show;
  animation-duration: 0.2s;
  animation-fill-mode: backwards;
}

@keyframes show {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

実行後のHTML

<p class="txt">
        <span class="line"><span class="txtInner" style="animation-delay: 0.03s;"></span><span class="txtInner" style="animation-delay: 0.06s;"></span><span class="txtInner" style="animation-delay: 0.09s;"></span><span class="txtInner" style="animation-delay: 0.12s;"></span><span class="txtInner" style="animation-delay: 0.15s;"></span></span>
        <span class="line"><span class="txtInner" style="animation-delay: 0.18s;">1</span><span class="txtInner" style="animation-delay: 0.21s;"></span><span class="txtInner" style="animation-delay: 0.24s;"></span><span class="txtInner" style="animation-delay: 0.27s;"></span><span class="txtInner" style="animation-delay: 0.3s;"></span></span>
        <span class="line"><span class="txtInner" style="animation-delay: 0.33s;"></span><span class="txtInner" style="animation-delay: 0.36s;"></span><span class="txtInner" style="animation-delay: 0.39s;"></span><span class="txtInner" style="animation-delay: 0.42s;"></span><span class="txtInner" style="animation-delay: 0.45s;"></span><span class="txtInner" style="animation-delay: 0.48s;"></span><span class="txtInner" style="animation-delay: 0.51s;"></span><span class="txtInner" style="animation-delay: 0.54s;"></span><span class="txtInner" style="animation-delay: 0.57s;"></span></span>
</p>

参考リンク

補足(animation-delayの秒数を設定をscssで行う)

成果物

See the Pen テキストアニメーション by miwa_shuntaro (@miwashutaro0611) on CodePen.

コード

.line {
  $defaultTime: 0;
  $aryNumber: 0;
  $animeTime: 0.03;
  @for $i from 1 through 10 {
    &:nth-of-type(#{$i}) {
      @for $j from 1 through 10 {
        .txtInner:nth-of-type(#{$j}) {
          $aryNumber: $aryNumber + 1;
          animation-delay: #{$defaultTime + $aryNumber * $animeTime}s;
        }
      }
    }
  }
}