LoginSignup
4
4

More than 1 year has passed since last update.

スクロールしたら一文字ずつアニメーション

Last updated at Posted at 2022-09-07

スクロールして特定の要素が画面に入ったら、
テキストアニメーションする実装をしたので備忘録として。

CodePen
https://codepen.io/yaajitaake4/pen/zYjvZBO

コード

HTML

index.html
<p class="text">スクロールしてください</p>

<div class="box"> 
  <div class="text-animation">アニメーション01</div>
</div>


<div class="box">
  <div class="text-animation">アニメーション02</div>
</div>

CSS(SCSS)

style.scss
// 余白用
.text {
  margin-bottom: 1000px;
}

.box {
  background-color: #eee;
  margin-bottom: 200px;
  padding: 100px 0;
}

// アニメーション用
.text-animation {
  opacity: 0;

  &.show {
    opacity: 1;

    .text-animation-span {
      display: inline-block;
      overflow: hidden;

    }
    span {
      display: inline-block;
      letter-spacing: 0.1em;
      animation: showText .5s backwards;
    }
  }
}

@keyframes showText {
  0% {
    opacity: 0;
    transform: translateY(100%);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

JavaScript

script.js
document.addEventListener('DOMContentLoaded', () => {
  const boxElement = document.querySelectorAll('.box');
  const textElement = document.querySelectorAll('.text-animation');

  // スクロールしたら表示
  document.addEventListener('scroll', () => {
    for (let i = 0; i < boxElement.length; i++) {
      // windowの上端から要素までの距離 + 要素の高さ(ここで表示のタイミングを調整)
      const getElement = boxElement[i].getBoundingClientRect().top + boxElement[i].clientHeight;

      if (window.innerHeight > getElement) {
        textElement[i].classList.add('show');
      }
    }
  });

  for (let i = 0; i < textElement.length; i++) {
    const textElements = textElement[i],
          animeText = textElements.textContent,
          animeTextArray = []; // spanタグで囲んだ文字を格納する

    textElements.textContent = ''; // 後ほど追加するので空に

    for (let j = 0; j < animeText.split('').length; j++) {
      const t = animeText.split('')[j]; // 文字を分割

      if (t === ' ') {
        animeTextArray.push(' '); // スペースはそのまま格納
      } else {
        animeTextArray.push( // テキストをspanタグで囲む
          '<span class="text-animation-span"><span style="animation-delay: ' + j * 0.1 + 's">' + t + '</span></span>'
        );
      }
    }

    // 囲んだ要素を追加
    for (let k = 0; k < animeTextArray.length; k++) {
      textElements.innerHTML += animeTextArray[k];
    }
  }
});

今後はintersectionObserverやreduceメソッドを使ったり、
改良していきたいなと思います。

4
4
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
4
4