jQueryとCSSのtransitionで可視範囲に入ってからアニメーションさせる方法
可視範囲になってから表示されたり動いたり、スクロールに応じてアニメーションさせる方法を紹介します。動きをつけて目を引くことで、効果的に伝えることができるかもしれません。
以前、「jQueryを使って、スクロールしてコンテンツが現れたときにアニメーションさせてみる|Webpark」という記事で同じようなものを紹介したのですが、デモが気に入っていない、アニメーションが1度きりということで作り変えました。
まずはサンプルをご覧ください。スクロールするとアイコンとテキストが順番にフェードインします。
このサンプルで使われている、画面いっぱいに表示する方法と、上にスクロールしたときに現れるメニューは以前紹介しています。気になる方はどうぞ。
ということで本題に入ります。
まずはHTMLから。
<div class="effect">
<i class="fa fa-child fa-5x"></i>
<div>
<h2>Section2</h2>
<p>スクロールするとアイコンとテキスト順番に現れます</p>
</div>
</div>
.effectが指定した場所までスクロールすると、子要素であるiとdivがアニメーションします。jQueryではCSSの値を変更するだけで、transitionを使って動きをつけています。
アイコンはFont Awesomeを使っています。以前記事にしていますので気になる方はぜひご覧ください。
CSSはこんな感じです。動きを付ける部分のみです。
.effect i {
height: 120px;
padding: 20px;
font-size: 100px;
transition: .8s;
}
.effect div {
margin: auto;
transition: .8s;
transition-delay: .8s;
}
順番に表示させるため、片方にtransition-delayを使っています。サイトに合せて自由に変更すればいいので参考程度にどうぞ。
で、メインのjQueryです。
$(function(){
$('.effect div, .effect i').css("opacity","0");
$(window).scroll(function (){
$(".effect").each(function(){
var imgPos = $(this).offset().top;
var scroll = $(window).scrollTop();
var windowHeight = $(window).height();
if (scroll > imgPos - windowHeight + windowHeight/5){
$("i, div",this).css("opacity","1" );
$("i",this).css({
"font-size": "100px",
"padding": "0 20px 40px"
});
} else {
$("i, div",this).css("opacity","0" );
$("i",this).css({
"font-size": "20px",
"padding": "20px"
});
}
});
});
});
では部分ごとで簡単に解説します。
$('.effect div, .effect i').css("opacity","0");
アニメーションの対象となる.effect divと .effect iの表示を消します。CSSで非表示にしてもいいですが、それだとjavascriptが機能しない場合に表示されません。javascriptで非表示にすると、javascriptが機能しない場合、非表示にならなければアニメーションもせず、ということで最初から表示された状態になります。
$(window).scroll(function (){
$(".effect").each(function(){
スクロールした際に.effectごとに、これ以下に記述する内容が実行されます。
var imgPos = $(this).offset().top;
var scroll = $(window).scrollTop();
var windowHeight = $(window).height();
変数を指定します。imgPosは、.effectの位置、scrollはスクロールした量、windowHeightはウインドウの高さです。
if (scroll > imgPos - windowHeight + windowHeight/5){
アニメーションする条件になります。.effectが画面の下から1/5のところまでスクロールする、というのが条件になります。ちょっとややこしいので図にしています。
可視範囲に入ってすぐにアニメーションが始まると、下の方がまだ画面に入っていない可能性もあります。なので、指定した高さまで達した時点でアニメーションさせるようにします。今回の場合は、スクロールして.effectが画面の下から1/5まできた時点でアニメーションするようになります。
ピクセルで指定してもいいですが、画面サイズも色々ですので画面サイズを元に指定しています。
$("i, div",this).css("opacity","1" );
$("i",this).css({
"font-size": "100px",
"padding": "0 20px 40px"
});
} else {
$("i, div",this).css("opacity","0" );
$("i",this).css({
"font-size": "20px",
"padding": "20px"
});
}
最後はアニメーションの内容です。とはいっても今回はCSSのtransitionを使っているのでCSSの内容を変えるだけです。
まず、iとdivを表示させます。divはtransition-delayを指定しているので、後で表示されます。
あと、アイコンも大きくします。paddingは真ん中から大きくなるようにするために調整するためです。
else以降は、スクロールで上に戻った際に、元に状態(表示なし)に戻すためのものです。
おまけ
このサンプルの最初にある、一定以上スクロールすればフェードアウトする方法も載せておきます。
$(function(){
$(window).scroll(function (){
var scroll = $(window).scrollTop();
var windowHeight = $(window).height();
if(scroll >= windowHeight/5) {
$('#centerBoxFirst').fadeOut();
} else {
$('#centerBoxFirst').fadeIn();
}
});
});
スクリーンの1/5以上スクロールすれば、#centerBoxFirstがフェードアウトし、上に戻るとフェードインします。
さいごに
ということで、可視範囲に入ったらアニメーションする方法と、おまけで一定以上スクロールすればフェードアウトする方法を紹介しました。
高さとスクロールの計算はイメージしずらいかもしれませんが、慣れると色々できて便利だと思います。
アニメーションの仕方など色々考えられますので、これを参考に遊んでもらえればうれしいです。
※コメントはご意見ご感想や間違いのご指摘等にしていただけますようお願いいたします。ブログに費やせる時間が限られており、技術的なご質問をいただいても答えできません。申し訳ございませんがご理解いただければ幸いです。