パララックスサイトや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

パララックスサイトの様に
スクロールして要素が出現した時点でアニメーション処理実行させる際にぜひ。。。

サンプルファイルをダウンロードしたい方はこちらから

SHARE

Comments (8)

  • caramel | 2014.10.30 13:43

    いつもわぁすごい&楽しく拝見させていただいています。

    ひとつご質問なのですが、画像が表示されたあとは
    フェードアウトしないようにはできたりするのでしょうか?
    また個々の画像に違う動きを設定することは可能なのでしょうか?

    よろしければ、お答え頂けたら幸いです。
    よろしくお願いします。

  • caramel | 2014.10.31 17:49

    たびたび申し訳ありません。

    表示後、フェードアウトをしない形は上記にあるように
    21行目下をコメントアウトすることで、解決できましたが、
    スクロールしないトップにある状態で、フェードインすることは
    可能でしょうか?

    よろしければ、お答え頂けたら幸いです。
    よろしくお願いします。

  • BlackFlag | 2014.11.02 1:17

    >caramelさん
    コメントありがとうございます。
    当記事のスクロールスクリプトをご検証いただいている様で
    嬉しく思っております。

    ご質問いただいた件についてですが
    スクロールしないトップの状態(ページロード時)でも
    アニメーション動作は実行される仕様になっていると思います。

    一度サンプルファイルを編集してみて
    ご確認いただければと思っております。

    よろしくお願いします。

  • otzi | 2014.12.12 15:28

    こんにちは。
    以前、フリック/スワイプ動作の画像スライドギャラリーでお世話になったものです。
    今回、スクロール動作によってブロック要素の表示⇄非表示の切り替えを行いたいと思い、displayプロパティをnoneとblockで切り替える方法を試してみましたが上手くいきません。どうも初期値でdisplayプロパティをnoneにするとanimate() メソッドは機能しないようです。
    ただ色々試して見たところ、animate() を適用する要素のheightを0と要素本来の値で切り替えるという方法でほぼイメージした通りの結果が得られました。
    もっともこれが方法として適切なのかどうかは分りませんが。
    ともあれ、今回も貴重なアイディアの提供に感謝申し上げます。

  • BlackFlag | 2014.12.14 1:36

    >otziさん
    コメントありがとうございます。

    CSSでもともと「display:none」になっている要素に対しては
    jQueryで指定が効かないものはいろいろありますが
    画面を切り替える時の「表示」する際のアクションで
    実行スクリプトが動作するように構成すれば大丈夫かと思います。

    また同じような機会がありましたらお試しください。
    よろしくお願いします。

  • パララックス/スクロールでアニメーションさせるjQueryプラグインなど | モノづくりブログ - 株式会社8bit | 2015.02.27 12:01

    […] jQueryでパララックスサイトの様にスクロールして要素が出現した時点でアニメーション等のイベント処理を実行させる実験-BlackFlag様 […]

  • hoshitaimoimo | 2015.04.10 15:00

    こんにちは。いつもお世話になっております。

    1つ質問があります。

    fullpage.js とこちらのアニメーションの動きを組み合わせたいのですが、
    2ページ目以降のアニメーションが動かないのです。

    不思議なことに、ネットまたはプレビュー画面で「ブラウザのサイズを変更」したところ
    1ページ目同様、アニメーションが表示されました。

    お手すきの際にでもお答えいただけたら幸いです。
    どうぞよろしくお願いいたします。

  • BlackFlag | 2015.04.12 11:57

    >hoshitaimoimoさん
    コメントありがとうございます。
    当記事のスクロールスクリプトをご検証いただいている様で
    嬉しく思っております。

    「fullPage.js」プラグイン動作については
    このプラグインをちゃんと使ったことがないので何とも言えませんが
    他ブログ様の記事になりますが「Kana-Lier」さんの「fullPage.js」に関する記事

    ・fullPage.jsで1つのコンテンツをスクロールして表示させたあとにJavaScriptを実行する | Kana-Lier カナリエ
    http://kana-lier.com/javascript/fullpage-js/

    こちらが参考になるのではないでしょうか。

    ご確認ください。
    よろしくお願いします。







コメント内容

※コメントにHTMLタグを直接入力しないでください。
※HTMLタグを入力する際はタグ一つ一つの括弧「<」「>」を全角に変換して入力してください。

コメントは承認制になっているのですぐには反映されません。コメント頂いた内容については出来る限り早めの対応を心掛けていますが、時期によって返答が遅くなってしまうことがありますので、何卒ご了承ください。
» コメントについてのご注意  |  » ライセンスに関して