パララックスサイトやAppleのプロダクトページの様な動きを付ける為の
スクロールして特定の位置でアニメーション等の処理を実行させることができる
jQueryプラグイン等をここでも何度か紹介しましたが
プラグインのバージョンによって動作仕様が変わってしまっていたり
上からのスクロールと、下からのスクロールの判断が微妙だったりしたので
なんとか簡単にスクロールの上下を判別させて、
なにか処理を実行させるスクリプトができないものか
試しに作ってみたので紹介してみます。
jQueryでパララックスサイトの様にスクロールして要素が出現した時点でアニメーション等のイベント処理を実行させる実験
まずはサンプルから。
下記の画面をスクロールするとコンテンツ要素が順々にフェードインします。
「jQueryでパララックスサイトの様にスクロールして要素が出現した時点でアニメーション処理実行させる実験」サンプルを別枠で表示
上記サンプルでは6つコンテンツエリアを縦に配置してあります。
上からスクロール(ダウン)してそれぞれのコンテンツエリアに達した(※)際に
フェードアニメーションを使ってエリア全体を出現させています。
逆に下からスクロール(アップ)していくと
コンテンツエリアに到達した(※)際にフェードアウトするようになっています。
※正確にはコンテンツエリアに達して100px過ぎた地点
動作仕様については以上になります。
全体構成についてまずはHTMLから。
◆HTML <div id="field1" class="scrEvent">ここは コンテンツエリア【1】 です</div><!--/#field1--> <div id="field2" class="scrEvent">ここは コンテンツエリア【2】 です</div><!--/#field2--> <div id="field3" class="scrEvent">ここは コンテンツエリア【3】 です</div><!--/#field3--> <div id="field4" class="scrEvent">ここは コンテンツエリア【4】 です</div><!--/#field4--> <div id="field5" class="scrEvent">ここは コンテンツエリア【5】 です</div><!--/#field5--> <div id="field6" class="scrEvent">ここは コンテンツエリア【6】 です</div><!--/#field6-->
スクロール時のイベントを実行させる要素に対して
任意のクラス(もしくはID)を付与します。
※サンプル上では「class=”scrEvent”」としています。
イベントを発生させる要素に対して
クラス(もしくはID)の付与以外には特に特別な指定はありません。
これに対してCSSは以下の様になっています。
◆CSS /* field ------------------------- */ #field1 {background: #fff;} #field2 {background: #eee;} #field3 {background: #ddd;} #field4 {background: #ccc;} #field5 {background: #bbb;} #field6 {background: #aaa;} .scrEvent { padding: 20px; height: 500px; text-align: left; border-top: #000 1px solid; border-bottom: #000 1px solid; display: none; }
CSSについては、スクロールイベントを発生させる要素には
「display: none;」を入れておきます。
それ以外のプロパティは特に特別な指定はなく
サンプル画面のレイアウトを成形する為のものになっております。
そして実際の動作スクリプトは以下の様になります。
◆SCRIPT <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script> $(function(){ var setElm = $('.scrEvent'), delayHeight = 100; setElm.css({display:'block',opacity:'0'}); $('html,body').animate({scrollTop:0},1); $(window).on('load scroll resize',function(){ setElm.each(function(){ var setThis = $(this), elmTop = setThis.offset().top, elmHeight = setThis.height(), scrTop = $(window).scrollTop(), winHeight = $(window).height(); if (scrTop > elmTop - winHeight + delayHeight && scrTop < elmTop + elmHeight){ setThis.stop().animate({opacity:'1'},500); // 【上】からスクロールしてきた時のイベント } else if (scrTop < elmTop - winHeight + delayHeight && scrTop < elmTop + delayHeight){ setThis.stop().animate({opacity:'0'},500); // 【下】からスクロールしてきた時のイベント } }); }); }); </script>
スクリプト開始部分にある設定値の内容は以下の様になっています。
var setElm = $(‘.scrEvent’) | スクロールイベントを発生させる要素名(IDでも可) |
---|---|
delayHeight = 100 | 要素から何px過ぎたらイベントを実行させるか |
これらの設定値を変更することで調整が可能になっています。
スクリプト18~22行目のif文で囲われた部分が
アニメーション等の実際の動き(イベント動作)を付ける箇所となり、
スクリプト19行目には上からスクロール(ダウン)してきた場合のイベント処理、
スクリプト21行目には下からスクロール(アップ)してきた場合のイベント処理を記述します。
サンプルでは、上からスクロールしてきた際にはフェードイン、
下からスクロールしてきた際にはフェードアウトするアニメーションを記載しています。
ページをスクロールして、
「var setElm = $(‘.scrEvent’)」で指定している要素にスクロール位置が到達し、
「delayHeight = 100」で設定している値の数(px)だけ要素から通り過ぎた際に
スクリプト処理が実行されます。
要素の位置に到達した時点ですぐにスクリプト処理を実行させたい場合には
「delayHeight = 0」と指定します。
上記サンプルでは、エリア全体をフェードアニメーションで表示/非表示を切り替えていますが
画像など特定要素に対して行う場合は以下の様になります。
画像出現アニメーションパターン
こちらのパターンでのHTMLは以下のようになります。
◆HTML <div id="field1"><img src="img/photo1.jpg" class="scrImg"></div><!--/#field1--> <div id="field2"><img src="img/photo2.jpg" class="scrImg"></div><!--/#field2--> <div id="field3"><img src="img/photo3.jpg" class="scrImg"></div><!--/#field3--> <div id="field4"><img src="img/photo4.jpg" class="scrImg"></div><!--/#field4--> <div id="field5"><img src="img/photo5.jpg" class="scrImg"></div><!--/#field5--> <div id="field6"><img src="img/photo6.jpg" class="scrImg"></div><!--/#field6-->
こちらのサンプルパターンでは
エリアに対してクラスを付与するのではなく
画像に対してクラス「.scrImg」をつけています。
これに対してCSSは以下の様になっています。
◆CSS /* field ------------------------- */ #field1, #field2, #field3, #field4, #field5, #field6 { padding: 20px 0; width: 100%; height: 300px; text-align: center; border-top: #000 1px solid; border-bottom: #000 1px solid; overflow: hidden; } #field1 {background: #fff;} #field2 {background: #eee;} #field3 {background: #ddd;} #field4 {background: #ccc;} #field5 {background: #bbb;} #field6 {background: #aaa;} .scrImg { left: -100px; margin: 0 auto; display: none; position: relative; }
「.scrImg 」に対して、「display: none;」を入れておきます。
そして実際の動作スクリプトは以下の様になります。
◆SCRIPT <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script> $(function(){ var setElm = $('.scrImg'), delayHeight = 200; setElm.css({display:'block',opacity:'0'}); $('html,body').animate({scrollTop:0},1); $(window).on('load scroll resize',function(){ setElm.each(function(){ var setThis = $(this), elmTop = setThis.offset().top, elmHeight = setThis.height(), scrTop = $(window).scrollTop(), winHeight = $(window).height(); if (scrTop > elmTop - winHeight + delayHeight && scrTop < elmTop + elmHeight){ setThis.stop().animate({left:'0',opacity:'1'},500); } else if (scrTop < elmTop - winHeight + delayHeight && scrTop < elmTop + delayHeight){ setThis.stop().animate({left:'-100px',opacity:'0'},500); } }); }); }); </script>
スクリプト19行目の上からスクロールしてきた場合のアニメーション処理と
スクリプト21行目には下からスクロールしてきた場合のアニメーション処理にて
画像を左からスライドしながらフェードイン/アウトさせるように記述しています。
この様な構成でパララックスサイトでのエフェクトの様に
ある特定の位置までスクロールした際に
要素に対してアニメーションなどの処理を実行させることが出来る様になります。
パララックスサイトだけでなく通常のWebサイトでも
特定の位置にスクロールが到達した時点で
要素に何かアクションを与えることで
重要視させるポイントを効果的に魅せることも可能かと思っています。
今回のスクロール位置を判別するスクリプトでは
下記のWebparkさんの記事を参考にさせていただきました。
ありがとうございます。
【参考記事】jQueryを使って、スクロールしてコンテンツが現れたときにアニメーションさせてみる|Webpark
パララックスサイトの様に
スクロールして要素が出現した時点でアニメーション処理実行させる際にぜひ。。。