jQuery基礎講座:スクロールして要素が出現したらアニメーションを実行する方法(ZIP付)
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(上の埋め込み画像にみる内容)を作ったので、是非実際に動作を確認してみて下さい。
最後に
上記サンプル内容をまとめた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.(訳:最後まで読んでくれてありがとう。 / 注:ズールー語)
Pingback: jQuery基礎講座:スクロールに応じたビジュアルの拡大・移動で、パララックスライクなお手軽錯視効果を実装する(ZIP付) | 株式会社パナレア()
Pingback: jQuery基礎講座:するっと動くドロワーメニューの作り方(ZIP付) | 株式会社パナレア()