スクロールして徐々にテキストを表示する方法
テーマ「ShapeShifter」バージョン1.0.9で取り入れたCSSアニメーションの実装方法についてです。
まぁ通常必要ない機能だとは僕自身思ったんですが、敢えて非表示にして、スクロールすると見えるようにすると、
僕はCSSアニメーションにサードパーティ製の「Animate CSS」を使用していますが、その他のCSSアニメーションをお持ちであれば、それで問題ありません。
サンプルは現在このページのコンテンツにも使用されているものを見ていただければと思いますが、モバイル端末ではCSSアニメーション効果は付かないようにしていますので、確認の際はJavaScriptを読むパソコンのブラウザでお願いします。
スクロール時のCSSアニメーションの使い方
まず、CSSアニメーションのクラスが必要になりますので、何も準備のない場合は、「Animate.css」でCSSダウンロードしておきましょう。
その他は特に必要がありませんので、アップロードしたら読まれるようにしておきましょう。
作業する順番は特に無いのですが、項目ごとに分けて解説していきます。
CSSの準備
新たに非表示用のクラスを準備しておきます。
スクロールで表示される前の状態に使用するクラスです。
例えば、
.something-hidden { visibility: hidden; }
のようなクラスを通常読まれるCSSに追記しておきます。プロパティは「visibility」じゃなくても何でも良いのですが、クラス名はBootstrapのクラスメイト重複するので「hidden」を避けています。
HTMLの準備
任意の要素にスクロール時にアニメーションで表示するようにクラスを与えます。
僕は「enter-animated」というクラスを与えて、これをスクロール時にJSで探すようにし、同時に上でCSSに追記した非表示用のクラスも与えておきます。
また、データ属性を使ってCSSアニメーションのクラス名を与えておきます。
<p class-"something-hidden enter-animated" data-animation-enter="">表示するテキスト</p>
こんな感じです。
つまり、条件を満たした時に
$( '.enter-animated' ).remove( 'something-hidden' ); $( '.enter-animated' ).doSomething(); // CSSアニメーションのクラスを与える処理をする。
といった感じで処理できるようにしておきます。
JSファイルの準備
簡単に処理できる関数が「Animate.css」の中にも用意されています。
jQuery.fn.extend({ animateCss: function (animationName) { var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend'; $(this).addClass('animated ' + animationName).one(animationEnd, function() { $(this).removeClass('animated ' + animationName); }); } });
jQueryを拡張するようにして、コードの最初にこれを追記します。
これが読まれると、指定したセレクターに引数として与えたアニメーションクラスを与え、アニメーションが終わると与えたクラスを取り除いてくれます。
jQuery.fn.extend({ animateCssEnter: function ( hiddenClass, animationName ) { $( this ).removeClass( hiddenClass ); var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend'; $( this ).addClass( 'animated ' + animationName ).one( animationEnd, function() { $( this ).removeClass( 'animated ' + animationName ); }); } });
といった感じにしても良いと思います。
違いは非表示クラスを引数として用い、「アニメーションの前に非表示を解除する」というだけです。
実際にこれを使用してみると以下のようになります。
( function( $ ) { $( document ).ready( function() { var handleAnimationEnter = function( selector, scrollTop, scrollBottom ) { // HTMLに与えた非表示クラス名 var hiddenClass = 'something-hidden'; $( selector ).each( function( index ) { var item = $( selector )[ index ]; $this = $( item ); animationEnter = $this.data( 'animation-enter' ); if( typeof animationEnter === 'undefined' ) { animationEnter = 'fadeIn'; } var itemOffsetTop = $this.offset().top; var itemOffsetBottom = $this.outerHeight() + itemOffsetTop; if( itemOffsetBottom < scrollTop || scrollBottom < itemOffsetTop ) { // ウィンドウの外 } else { // 要素がウィンドウ内にある if( $this.hasClass( hiddenClass ) ) { $this.animateCssEnter( hiddenClass, animationEnter ); } } } ); }; var handleScrollAnimateClass = function() { var scrollTop = $( window ).scrollTop(); var scrollBottom = scrollTop + $( window ).innerHeight(); handleAnimationEnter( '.enter-animated', scrollTop, scrollBottom ); }; // モバイルではない場合 // サイトの環境にも夜と思いますので、「isMobile」はご自身で定義してください。 if( ! isMobile ) { $( window ).on( 'load', function() { handleScrollAnimateClass(); }); // スクロール $( window ).on( 'scroll', function() { handleScrollAnimateClass(); }); } }); }) ( jQuery );
といった感じでしょうか。
表示条件の「 itemOffsetBottom < scrollTop || scrollBottom < itemOffsetTop 」は都合のいいように設定すれば良いと思います。
あと、コード内のコメントにも書きましたが、「isMobile」はご自身で定義してください。
ワードプレスで使用する場合のオプション

テーマ「ShapeShifter」でも実装していますが、ワードプレスではテーマカスタマイザーでアニメーションを設定することも可能です。
コンテンツ内はフィルターを使うことが理想的ですが、バージョン1.0.9では正規表現が上手く行かず、代替的にJSでクラスを与えて処理していますので、最初にちょっとテキストが見えるのはそのためです。テスト環境ではちゃんと正規表現が上手くいっているのですが、こちらのサイトで実際に使ってみると駄目でした。恐らくどこか見落としていたんだと思いますので、次のバージョンでは上手く動作するようにしようと思っています。
また、ピクセル指定して、表示されるタイミングを早めたり遅くしたりすることも可能です。
実際にテーマ「ShapeShifter」では「50px」遅く読まれるようにしています。まぁ本当に僅かな差なんで、これもテーマカスタマイザーで調節出来るようにしたいとは思っています。
1件のピン
[…] で動かす仕組みについては「スクロールして徐々にテキストを表示する方法」を参照してください。 […]