スクロールでふわっと現れるフェードインの動きをjQueryで実装

web
この記事の結論
  • すぐに実装したい方はこちら
  • フェードは雰囲気作りや強調に使うのが効果的。
  • ブログは文章がメインなのであまり適していない。アイキャッチなどを強調するならOK

ホームページでよく見かける
スクロールすると要素がふわっとフェードする動きありますよね。

具体的には以下のような感じ。

薔薇
アンプ

  • あーこれか。見たことあるな。なんかオシャレっぽいやつな
  • どうやらフェードがこの記事にも実装されているようですね。
  • ぶっちゃけブログだと見づらいよね。
    文章読みたいだけなのに何フェードしてんだよっていう

このようなふわっとした動きは、
jQueryのプラグインを使えば簡単に実装することは出来るのですが、
今回は備忘録も兼ねて1から作ってみました。

コメントも入れているので、
jQueryを勉強中の方は是非参考にしてみてください。

完成コード

まずは今回作ったコードを先に載せておきます。
そのままコピペで動きます。

html

<div class="scroll-fade">
    この要素がフェードします。
</div>
jQuery

$(function(){
    var effect_pos = 300; // 画面下からどの位置でフェードさせるか(px)
    var effect_move = 50; // どのぐらい要素を動かすか(px)
    var effect_time = 800; // エフェクトの時間(ms) 1秒なら1000

    // フェードする前のcssを定義
    $('.scroll-fade').css({
        opacity: 0,
        transform: 'translateY('+ effect_move +'px)',
        transition: effect_time + 'ms'
    });

    // スクロールまたはロードするたびに実行
    $(window).on('scroll load', function(){
        var scroll_top = $(this).scrollTop();
        var scroll_btm = scroll_top + $(this).height();
        effect_pos = scroll_btm - effect_pos;

        // effect_posがthis_posを超えたとき、エフェクトが発動
        $('.scroll-fade').each( function() {
            var this_pos = $(this).offset().top;
            if ( effect_pos > this_pos ) {
                $(this).css({
                    opacity: 1,
                    transform: 'translateY(0)'
                });
            }
        });
    });
});

フェードさせたい要素にscroll-fadeclassを追加してください。
スクロールの位置やタイミングを変更したいときは、
プログラム内の以下部分を変更してください。

var effect_pos = 300; // 画面下からどの位置でフェードさせるか(px)
var effect_move = 50; // どのぐらい要素を動かすか(px)
var effect_time = 800; // エフェクトの時間(ms) 1秒なら1000

スクロールフェードの効果的な使い方

これは個人的な意見なのですが、
ブログ記事にはフェードはあまり適していません。

なぜなら、ブログを読む人たちは、
文章を読むことが目的なので、アニメーションはかえって読むことの邪魔になるからです。
ただ、ブログでも、アイキャッチなどの画像を強調したい場合は良いかなとか思ったりします。

フェードのようなアニメーションは

  • 女性向け(美容やファッションなど)のサイトで柔らかい雰囲気を作りたいとき
  • 商品紹介やアプリ紹介などのLPで、画像、値段、機能などに注目を集めたいとき
  • 画像のギャラリーなど、おしゃれな雰囲気を作りたいとき

などが効果的だと自分は考えています。

  • 美容系や旅館などのホームページでは柔らかい雰囲気を作るために
    フェードを利用している印象がありますね。
  • ようは、使いどころを見極めろってことだな

フェード効果の応用編

少しアレンジすると、
連続する要素を少しずつずらしてフェードをすることもできます。
スクロールしてみてください。

通常

1
2
3
4
5

連続でフェード

1
2
3
4
5
html

<div class="ex1 scroll-fade-row">
    <div><span>1</span></div>
    <div><span>2</span></div>
    <div><span>3</span></div>
    <div><span>4</span></div>
    <div><span>5</span></div>
</div>
css

.ex1 {
    display: flex;
    justify-content: space-between;
}
.ex1 div {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100px;
    height: 100px;
    background-color: #e45151;
}
jQuery

$(function(){

    var effect_btm = 300; // 画面下からどの位置でフェードさせるか(px)
    var effect_move = 50; // どのぐらい要素を動かすか(px)
    var effect_time = 800; // エフェクトの時間(ms) 1秒なら1000

    //親要素と子要素のcssを定義
    $('.scroll-fade-row').css({
        opacity: 0
    });
    $('.scroll-fade-row').children().each(function(){
        $(this).css({
            opacity: 0,
            transform: 'translateY('+ effect_move +'px)',
            transition: effect_time + 'ms'
        });
    });

    // スクロールまたはロードするたびに実行
    $(window).on('scroll load', function(){
        var scroll_top = $(this).scrollTop();
        var scroll_btm = scroll_top + $(this).height();
        var effect_pos = scroll_btm - effect_btm;

        //エフェクトが発動したとき、子要素をずらしてフェードさせる
        $('.scroll-fade-row').each( function() {
            var this_pos = $(this).offset().top;
            if ( effect_pos > this_pos ) {
                $(this).css({
                    opacity: 1,
                    transform: 'translateY(0)'
                });
                $(this).children().each(function(i){
                    $(this).delay(100 + i*200).queue(function(){
                        $(this).css({
                            opacity: 1,
                            transform: 'translateY(0)'
                        }).dequeue();
                    });
                });
            }
        });
    });

});

基本は先ほどと一緒です。
ポイントは以下の部分です。

$(this).children().each(function(i){
    $(this).delay(100 + i*200).queue(function(){
        $(this).css({
            opacity: 1,
            transform: 'translateY(0)'
        }).dequeue();
    });
});

jQueryのeachではindexを取得することができます。
indexとは、上記プログラムのiのことで、何番目の要素であるかを取得することができます。

今回は、.scroll-fade-rowの子要素は5つあるので、
iには0, 1, 2, 3, 4が入ります。

※indexは0から始まることに注意してください。

次に、delay(100 + i*200)をみてください。
delayは文字通り、処理を遅延させる関数です。

今回は5つの要素があるので、これをiに当てはめていくと、

delay(100 + 0*200) = delay(100)
delay(100 + 1*200) = delay(300)
delay(100 + 2*200) = delay(500)
delay(100 + 3*200) = delay(700)
delay(100 + 4*200) = delay(900)

※単位はms

とすこしずつ遅れていくのが分かります。
これが少しずつずれてフェードする理由です。

最後に、delayさせた要素にcssを当てるため、
queue関数を使っています。

queueに関してはここでは詳しく話しませんが、
delayはアニメーションにしか効かないため、
queueを使って上手く処理します。

ガーっと駆け足で説明したので一気に理解するのは難しいと思いますが、
とりあえずコピペで動くので試してみてください。

参考サイト

jQueryのeach()メソッドの基本的な使い方

jQueryのeach()メソッドの基本的な使い方

jQuery で5秒後とかに addClass したいとき
https://github.com/shikakun/tips/issues/61

まとめ

フェード効果は使い道を誤ると、むしろユーザーの離脱に影響しかねないので、
使う場面は選んだほうが良いかと思います。

例えば、ポートフォリオサイトなどでは個性を出すために使うのは効果的だと個人的には思いますね!

また、プログラムの勉強がてら、スクロールフェードを自分で実装してみるのも面白いかもしれません。是非、参考にしてみてください。

シェアする