マメな人はバカであれ

バカなりに考えて、バカなりに行動します

技術的なことや、趣味的なことや、私生活的なことを書いてきます

jQueryで簡単にスクロールでスライドアニメーション(TweenMax)

仕事をしているとスクロールして「スッ…」ってスライドアニメーションとかつけること多い。
なので私は汎用できるスクロールでスライドアニメーションできるように、
jQueryと今回はTweenMaxで実装します。


まずは変数作ろう

/* --- Common variable --- */
var $window = $(window);
var ww = $window.width();
var wh = $window.height();
var s_top = $window.scrollTop();
var _sTop;
var _sBtm;

/* --- スライドフェードイン --- */
var $slideIn = $(".js-slideIn");
var slideInArr = [];
var slideInFlagArr = [];
var slideInTopArr = [];
$slideIn.css('opacity', 0);
    
var $staggerSlide = $(".js-staggerSlide");
var staggerSlideArr = [];
var staggerSlideFlagArr = [];
var staggerSlideTopArr = [];
$staggerSlide.children("*").css('opacity', 0);

ここで使う変数は上から順に説明すると
1. スライドさせる要素クラス名
2. スライドさせる要素クラス名を配列に入れる
3. 2.で配列に入れた要素がアニメーションしたかFlagをとる(Boolean)
4. 配列に入れた要素のoffset().topを取得(要素の高さ)

今回はスライド種類を作るので2セット分の変数を用意しています。


用意するコード

/* -----------------------------------------------
 * slideIn
 * ----------------------------------------------- */
/* 下から上へ */
$slideIn.each(function(i, ele) {
    var $this = $(ele);
    slideInArr[i] = $this;
    slideInFlagArr[i] = false;
    slideInTopArr[i] = $this.offset().top;
});


/* 連続した左から右 */
$staggerSlide.children().css("opacity","0");
$staggerSlide.each(function(i, ele) {
    var $this = $(ele);
    staggerSlideArr[i] = $this;
    staggerSlideFlagArr[i] = false;
    staggerSlideTopArr[i] = $this.offset().top;
});

説明しなくても大丈夫と思いますが、
eachでスライドさせる要素を各配列に入れて用意します。


アニメーションさせるコード

function slideInAnime($obj){
    TweenMax.fromTo($obj, .7, {y:20,opacity:0},{y:0,opacity:1,delay:.3,onComplete: function(){
        $obj.removeClass('js-slideIn');
    }});
}

function staggerSlideInAnime($obj){
    TweenMax.staggerFromTo($obj, .7, {x:20,opacity:0},{x:0,opacity:1,delay:.3},.15);
}

上のslideInAnime()は単純に下から上にスッ…ってスライドするアニメーション。
下のstaggerSlideInAnime()はTweenMaxのstaggerを使って連続して左から右へのアニメーションをさせるようにしています。

各TweenMaxのアニメーションについては公式サイトを見て下しあ

greensock.com

アニメーションにはTweenMaxを今回は使いますが、animateでもvelocity.jsでもanime.jsでもなんでもイイと思います。
正直TweenMaxは重たいので簡単な処理ならvelocity.jsを私はよく使いますが、みんなさんはどうなんでしょうね…


スクロールしたコード

/* -----------------------------------------------
 * - スクロール - 
 * ----------------------------------------------- */
$window.on('scroll', function (e) {
    e.preventDefault();
    _sTop = document.body.scrollTop || document.documentElement.scrollTop;
    wh = $window.height();
    _sBtm = _sTop + wh;

    /* スクロール アニメ */
    for (var i = 0; i < slideInArr.length; i++) {
        if (!slideInFlagArr[i] && slideInTopArr[i] <= _sBtm - 100) {
            slideInFlagArr[i] = true;
            slideInAnime(slideInArr[i]);
        }
    }

    for (var i = 0; i < staggerSlideArr.length; i++) {
        if (!staggerSlideFlagArr[i] && staggerSlideTopArr[i] <= _sBtm - 100) {
            staggerSlideFlagArr[i] = true;
            staggerSlideInAnime(staggerSlideArr[i].children());
        }
    }

});

スクロールしたら各要素のoffset().topを取得し格納した配列をここで使います。
スクロールした値をif文で判別し、判別したら用意したFlag配列をtrueにしてスライド済みというのを記録します。


これでスライドアニメーションはできると思いますが、
既存のコードからコピペして貼り付けているので、
これだけをコピペしたからといって使えるとは言っていませんのでご了承を。

読み込んだ時のスクロール位置

/* スクロール アニメ */
var wscroll = $window.scrollTop() + wh;
for (var i = 0; i < slideInTopArr.length; i++) {
    if (slideInTopArr[i] <= wscroll) { slideInFlagArr[i] = true; slideInAnime(slideInArr[i]); }
}
for (var i = 0; i < scaleInTopArr.length; i++) {
    if (scaleInTopArr[i] <= wscroll) { scaleInFlagArr[i] = true; scaleInAnime(scaleInArr[i]); }
}

リロードなどでページを読み込んだ時のスクロール位置が一番上でなく途中など中途半端な時、
$(document).ready(function(){});などで読み込んだ時に上記のコードを読み込むといいかもしれないですね。

読み込みタイミングに気をつければちゃんと動作すると思います。


最後に

よく使うであろうスクロールによるスライドアニメーションを汎用できるようにしてみました。
今回はclass名をつけるだけでアニメーションができるようにしましたが、
csstransformを設定している要素の場合は思った動きはしないと思いますので注意してくださいね。