https://idea-hack.com/blog/60595/
テキストアニメーションを実装するのに便利なSplitting.jsと4つの即席コード

テキストアニメーションを実装するのに便利なSplitting.jsと4つの即席コード

テキストアニメーションを実装するのに便利なSplitting.jsの仕様とサンプルコードをまとめました。

Splitting.jsはHTML要素の中にあるテキスト要素を行単位・単語単位・1文字単位など、設定を指定した上で<span>要素で区切って分けることができるJavascriptライブラリです。

このライブラリは、圧縮版で1.5kbと超軽量で非依存なので、サイト読み込み速度への影響をほとんど与えずに導入することができます。

また、このライブラリは、HTMLを分割させるだけで、JSファイル自体にはアニメーションに関する設定は入っていません。

アニメーションの設定は、自分で書く必要があります。

KAZUKI
CSSアニメーションに詳しくない人はtextillate.jsの方が使いやすいかもしれませんね。

使い方

CDNとNPMでのインストール方法が提供されています。

CDN

HTML
<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting.css" />
<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting-cells.css" />
<script src="https://unpkg.com/splitting/dist/splitting.min.js"></script>

NPM

npm
npm install splitting --save

コード集

通常、Splitting.jsはサイトの呼び出し時に実行されますが、本記事では挙動の確認をしやすいように、Splitting.jsが適用されるHTML要素に画面がスクロールした段階で読み込まれるようにしています。

そのための下準備として下記のコードを読み込ませています。

Javascript
  function isScrolledIntoView(elem) {
    var docViewTop = jQuery(window).scrollTop();
    var docViewBottom = docViewTop + jQuery(window).height();
  
    var elemTop = jQuery(elem).offset().top;
    var elemBottom = elemTop + jQuery(elem).height();
  
    if( elemBottom < docViewBottom) {
      if(elemTop > docViewTop) {
        return true;
      }
    }
  }
補足
[&]ではなく、[jQuery]を使っているのは、対WordPress対策になります。

デフォルト

まずはカスタマイズをせずにデフォルトで出力してみます。

Output
Hello World!
HTML
<div class="sample-1">
<div data-splitting>Hello World!</div>
</div>
CSS
/* Clear out these styles to start fresh or use this as a base! */
.splitting .char {
  animation: slide-in 1s cubic-bezier(.5, 0, .5, 1) both;
  animation-delay: calc(60ms * var(--char-index));
}

@keyframes slide-in {
  from {
    transform: translateY(-1em) rotate(-.5turn) scale(0.5);
    opacity: 0;
  }
}
Javascript
jQuery(function($){ 
$(window).scroll(function (){
 if( isScrolledIntoView( '.sample-1' ) ) {
   Splitting();
   };
});  
});

この時、HTMLソースでは下記のような変換が起きています。

HTML
<div data-splitting>Hello World!</div>
HTML
<div data-splitting=""  class="words chars splitting" style="--word-total:2; --char-total:11;"><span class="word" data-word="Hello" style="--word-index:0;">
<span class="char" data-char="H" style="--char-index:0;">H</span>
<span class="char" data-char="e" style="--char-index:1;">e</span>
<span class="char" data-char="l" style="--char-index:2;">l</span>
<span class="char" data-char="l" style="--char-index:3;">l</span>
<span class="char" data-char="o" style="--char-index:4;">o</span>
</span><span class="whitespace"> </span>
<span class="word" data-word="World!" style="--word-index:1;">
<span class="char" data-char="W" style="--char-index:5;">W</span>
<span class="char" data-char="o" style="--char-index:6;">o</span>
<span class="char" data-char="r" style="--char-index:7;">r</span>
<span class="char" data-char="l" style="--char-index:8;">l</span>
<span class="char" data-char="d" style="--char-index:9;">d</span>
<span class="char" data-char="!" style="--char-index:10;">!</span>
</span>
</div>

このように、HTML要素内のテキストそれぞれが、Span要素で囲まれていることがわかるでしょう。

デフォルトでは、1文字ごとに区切られています。

また、冒頭で申し上げたとおり、Splitting.jsはそれ自体がCSSアニメーションを含んでいるわけではなく、この記事では下記コードを読み込んでCSSアニメーションを独自に適用しています。

CSS
.splitting .char {
  animation: slide-in 1s cubic-bezier(.5, 0, .5, 1) both;
  animation-delay: calc(60ms * var(--char-index));
}

@keyframes slide-in {
  from {
    transform: translateY(-1em) rotate(-.5turn) scale(0.5);
    opacity: 0;
  }
}

Plugin(Words)

2つ目の例からは、対照的テキストの区切り方(デフォルトでは1文字ごと)に関するオプションを見ていきましょう。

KAZUKI
なお、JSコードはページ内に複数Splittingがあっても問題無い書き方に変えます。アニメーションは省略します。なのでOutPutの見た目はどれも同じです。
Output
Hello World!
HTML
<div id="sample-2">Hello World!</div>
Javascript
jQuery(function($){ 
  $(window).scroll(function (){
  if( isScrolledIntoView( '#sample-2' ) ) {
       Splitting({ target: "#sample-2", by: 'words' });
    };
  });  
});

変換後のHTMLは下記です。

HTML
<div id="sample-2" class="words splitting" style="--word-total:2;">
<span class="word" data-word="Hello" style="--word-index:0;">Hello</span>
<span class="whitespace"> </span>
<span class="word" data-word="World!" style="--word-index:1;">World!</span>
</div>

Plugin(lines)

こちらは行ごとにアニメーションを付与したいときに便利です。

Output
Hello
World!
HTML
<div id="sample-3">Hello <br/> World!</div>
Javascript
jQuery(function($){ 
  $(window).scroll(function (){
  if( isScrolledIntoView( '#sample-3' ) ) {
       Splitting({ target: "#sample-3", by: 'lines' });
    };
  });  
});

変換後のHTMLは下記です。

html
<div id="sample-3" class="words lines splitting" style="--word-total:2; --line-total:2;">
<span class="word" data-word="Hello" style="--word-index:0; --line-index:0;">Hello</span> <br> 
<span class="word" data-word="World!" style="--word-index:1; --line-index:1;">World!</span></div>

Plugin(items)

こちらは特定の要素内のHTMLタグ(デモではli)ごとにアニメーションを付与したいときに便利です。

Output
  • One
  • Two
  • Three
HTML
<div id="sample-4">
  <ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
  </ul>
</div>
Javascript
jQuery(function($){ 
  $(window).scroll(function (){
  if( isScrolledIntoView( '#sample-4' ) ) {
       Splitting({ target: "#sample-4", by: 'items', matching: 'li'  });
    };
  });  
});

変換後のHTMLは下記です。

HTML
<div id="sample-4" class="items splitting" style="--item-total:3;">
  <ul>
    <li style="--item-index:0;">One</li>
    <li style="--item-index:1;">Two</li>
    <li style="--item-index:2;">Three</li>
  </ul>
</div>

この他にも「grid」・「cols」・「rows」・「cells」がありますが、主だって利用するのは上記の4つかと思います。

アニメーションを適用するための下準備を節約できるので、サイトのトップページなどで使っていきましょう。