>
>
一文字ずつ下から出てくるテキスト

一文字ずつ下から出てくるテキスト

GSAPアニメーションスタイリッシュ
2026-05-17
2026-05-28
v3v4

スクロールして、指定の位置に来たら文字が一つづつ下から出てくるようなアニメーションをつけます。
v3とv4でJSコードが変わりますのでご注意ください。


1. クラス「anime-text」をウィジットにつけとく

2. 以下のCSS, JSを入れる

CSSコード

HTML
<style>
/* animation */
.anime-char-wrapper {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
}
.anime-char-inner {
  display: inline-block;
}
</style>

v3用のJSコード
(このコードの上にGSAP読み込みコードを入れてください。)

HTML
<script>
document.addEventListener('DOMContentLoaded', () => {
  gsap.registerPlugin(ScrollTrigger);

// --- animation text ---
  const animeElements = document.querySelectorAll('.anime-text');

  animeElements.forEach(container => {
    const titles = container.querySelectorAll('.elementor-heading-title');
    
    titles.forEach(title => {
      const wrapTextNodes = (el) => {
        const children = Array.from(el.childNodes);
        children.forEach(node => {
          if (node.nodeType === Node.TEXT_NODE) {
            const text = node.nodeValue;
            if (text.trim() === '') return;
            const fragment = document.createDocumentFragment();
            Array.from(text).forEach(char => {
              if (char.trim() === '') {
                fragment.appendChild(document.createTextNode(char));
              } else {
                const wrapper = document.createElement('span');
                wrapper.classList.add('anime-char-wrapper');
                
                const inner = document.createElement('span');
                inner.classList.add('anime-char-inner');
                inner.textContent = char;
                
                wrapper.appendChild(inner);
                fragment.appendChild(wrapper);
              }
            });
            el.replaceChild(fragment, node);
          } 
          else if (node.nodeType === Node.ELEMENT_NODE && node.tagName !== 'BR') {
            wrapTextNodes(node);
          }
        });
      };

      wrapTextNodes(title);
    });

    const chars = container.querySelectorAll('.anime-char-inner');

    gsap.fromTo(chars, 
      {
        yPercent: 115
      },
      {
        yPercent: 0,
        duration: 0.8,
        ease: "expo.out",
        stagger: 0.03,
        scrollTrigger: {
          trigger: container,
          start: "top 80%",
					toggleActions: "play none none reverse"
				}
      }
    );
  });
});
</script>

v4用のJSコード
(このコードの上にGSAP読み込みコードを入れてください。)

HTML
<script>
document.addEventListener('DOMContentLoaded', () => {
  gsap.registerPlugin(ScrollTrigger);

// --- animation text ---
const animeElements = document.querySelectorAll('.anime-text');

animeElements.forEach(container => {
  const wrapTextNodes = (el) => {
    const children = Array.from(el.childNodes);
    children.forEach(node => {
      if (node.nodeType === Node.TEXT_NODE) {
        const text = node.nodeValue;
        if (text.trim() === '') return;
        const fragment = document.createDocumentFragment();
        Array.from(text).forEach(char => {
          if (char.trim() === '') {
            fragment.appendChild(document.createTextNode(char));
          } else {
            const wrapper = document.createElement('span');
            wrapper.classList.add('anime-char-wrapper');
            
            const inner = document.createElement('span');
            inner.classList.add('anime-char-inner');
            inner.textContent = char;
            
            wrapper.appendChild(inner);
            fragment.appendChild(wrapper);
          }
        });
        el.replaceChild(fragment, node);
      } 
      else if (node.nodeType === Node.ELEMENT_NODE && node.tagName !== 'BR') {
        wrapTextNodes(node);
      }
    });
  };

  wrapTextNodes(container);

  const chars = container.querySelectorAll('.anime-char-inner');

  gsap.fromTo(chars, 
    {
      yPercent: 115
    },
    {
      yPercent: 0,
      duration: 0.8,
      ease: "expo.out",
      stagger: 0.03,
      scrollTrigger: {
        trigger: container,
        start: "top 80%",
        toggleActions: "play none none reverse"
      }
    }
  );
});
});
</script>

この記事をみんなにシェアしよう!!
Share!