読者です 読者をやめる 読者になる 読者になる

P N R A

東京都中野区に所在を構えるウェブ制作会社PNRA DESIGN OFFICE

jQuery基礎講座:スクロールして要素が出現したらアニメーションを実行する方法(ZIP付)

scroll-down

jQuery基礎講座[第7回]

どーも@PNRAです!
忘備録もかねて随時更新していくjQuery基礎講座の時間がやって参りました。

表題の通り、スクロールするとアニメーションを実行する、というものを作っていきたいと思います。これは、ウィンドウのスクロール量とアニメーションを実行する要素の位置関係を取得し、ウィンドウに出現するタイミングでクラスをつけてアニメーションを実行する、といった内容になっています。
前回の基礎講座(jQuery基礎講座[第6回]:スクロール量に応じて要素(ヘッダーなど)を固定する(ZIP付))と近しい内容になっているので、是非こちらも合わせて読んでみてください。

それでは、具体的にみていきましょう。

実装実例

どんな動きになるのかは下記画像内のウィンドウをスクロールしてご覧ください。(こちらは『placeit』で作成させていただきました。)

ページが読み込まれると、ファーストビュー部分のアニメーションが始まり、その後スクロールしてコンテンツエリアに来ると、別のアニメーションが始まります。

こちらからデモページもご覧いただけます。
Scroll animation DEMO

今回作成したデモ『Scroll animation』のポイントは、

jQueryでスクロール量と要素の相対位置を取得する。

・animate()を使う。

・addClass()で様々なアニメーションを実装する。

といった点です。

実装内容

順を追って説明をしていきたいと思います。

概要を掴む

スクロールしてアニメーションを発生させるには、
・アニメーションさせたい要素がウィンドウに出現するとクラスを付与
・付与させたクラスに内包する要素にアニメーションを指示
という指示が必要になってきます。

要素の高さを取得する

今回、スクロールして要素がウィンドウに出現した際に発生するアニメーションを実装するためには、スクロール量の深さ・ウィンドウの高さ・要素の最上部からの深さ・要素の高さが必要になってきます。これらを計算させて要素がウィンドウに出現する位置を取得し、.animate()、.addClass()、removeClass()を用いて、アニメーションを実行・解除していきます。

アニメーションさせる要素を定義する

まずはアニメーションさせる要素のブロックを定義します。今回はアニメーションさせる要素には、「.animate」を指定します。そこで、「.animate」の位置を取得するために、変数「setElm」に代入します。

//変数「setElm」を定義
var setElm = $('.animate');

またここではアニメーションの開始位置をスクロールしてから200px過ぎた位置で開始したいと思うので、以下を加える。

//変数「setElm」を定義
var setElm = $('.animate'),
delayHeight = 200;

変数「setElm」の詳細を決めていく

次に変数「setElm」の設定を行っていきます。
ここでは、要素の最上部からページトップまでの深さを「elmTop」、要素そのものの高さを「elmHeight」、スクロール量を「scrTop」、ウィンドウの高さを「winHeight」とします。

//変数「setElm」の詳細を定義する
var setElm = $(this),
elmTop = setElm.offset().top,
elmHeight = setElm.height(),
scrTop = $(window).scrollTop(),
winHeight = $(window).height();

変数「setElm」のタイミングを取得し、.animate()を与える。

タイミングは、出現するタイミングを「スクロール量」が「要素の最上部の高さからdelayHeight分を加えた位置」から「ウィンドウの高さ」の差を上回った際とそうでない場合に分けて考えます。

//if文で条件分岐させる
if (scrTop > elmTop - winHeight + delayHeight){
  setThis.stop().animate({opacity:'1'},500);
} else
if (scrTop < elmTop - winHeight + delayHeight){
  setThis.stop().animate({opacity:'0'},500);
}

同時にクラスを追加して、.animate()のタイミングでアニメーションを開始させる。

ここでは、.animate()メソッドを用いて、opacityを「0」から「1」に変えています。そのタイミングでクラスを付けるにはこのように記載します。

//if文で条件分岐させる
if (scrTop > elmTop - winHeight + delayHeight){
  setThis.stop().animate({opacity:'1'},500),
  setThis.addClass('クラス名');
} else
if (scrTop < elmTop - winHeight + delayHeight){
  setThis.stop().animate({opacity:'0'},500),
  setThis.addClass('クラス名');
}

これらをまとめて指示を記述する

ここまでみてきた内容をもとに、実行文を書いていくと、

JS

// アニメーションさせる要素を定義し、以下の処理を実行
$(function(){
 var setElm = $('.animate'),
 delayHeight = 200;
  setElm.css({position:'relative',display:'block',left:'0',opacity:'0'});
  $('html,body').animate({scrollTop:0},1);

// ウィンドウが読み込み、リサイズ、スクロールが始まると処理を実行
  $(window).on('load scroll resize',function(){

// 変数「setElm」が以下のいづれかの場合に処理を実行
   setElm.each(function(){
// 変数「setElm」のそれぞれの相対位置を取得
   var setThis = $(this),
   elmTop = setThis.offset().top,
   elmHeight = setThis.height(),
   scrTop = $(window).scrollTop(),
   winHeight = $(window).height();
// 変数「setElm」のそれぞれの相対位置を取得
    if (scrTop > elmTop - winHeight + delayHeight){
     setThis.stop().animate({left:'0',opacity:'1'},500),
     setThis.addClass('クラス名');
    } else
    if (scrTop < elmTop - winHeight + delayHeight){
     setThis.stop().animate({left:'0',opacity:'0'},500),
     setThis.removeClass('クラス名');
    }
   });
  });
 });

HTML

<body>

<sction class="animate">
<!-- ファーストビューコンテンツエリア -->
</sction>

<section class="animate">
<!-- メインコンテンツエリア -->
</section>

</body>

CSS

section.クラス名 > .要素名 .要素名 {
-webkit-animation: 'アニメーション名' '秒数' '動作' '開始時間';
-moz-animation: 'アニメーション名' '秒数' '動作' '開始時間';
animation: 'アニメーション名' '秒数' '動作' '開始時間';
}
@-webkit-keyframes {
'アニメーション実行内容'
}
@-moz-keyframes {
'アニメーション実行内容'
}
@keyframes {
'アニメーション実行内容'
}

CSS内に、addClass()の内部にある要素を要素名でクラスを与えて、そこにアニメーション指示を加えれば、jQueryでaddClass()された際に、その中にある要素がアニメーションするという指示が完成します。
僕の方でも簡単に実装したDEMO(上の埋め込み画像にみる内容)を作ったので、是非実際に動作を確認してみて下さい。

Scroll animation DEMO

最後に

上記サンプル内容をまとめたZIPファイルを用意したので、是非オリジナルにカスタマイズして使ってみて下さい。(かなりコードが汚いので後日修正します。)

ダウンロードはこちらから

ちょくちょく更新していきますので、是非こちらもご覧ください。

過去6回の記事はこちら
jQuery基礎講座[第1回]:任意のid属性を使ったクリックアクション
jQuery基礎講座[第2回]:ハンバーガーナビゲーションボタンを作ろう!
jQuery基礎講座[第3回]:ウィンドウサイズを取得してブラウザ100%のぴったりHeightを指定する!
jQuery基礎講座[第4回]:ハンバーガーナビゲーション実装サンプル(ZIP付)
jQuery基礎講座[第5回]:スクロール量に応じて出現するナビゲーションエリア(ZIP付)
jQuery基礎講座[第6回]:スクロール量に応じて要素(ヘッダーなど)を固定する(ZIP付)

参考にさせてもらった記事はこちら

Web park:jQueryを使った一定以上スクロールすると上に固定される横メニュー

Siyabonga ekufundeni kwakho.(訳:最後まで読んでくれてありがとう。 / 注:ズールー語)