waypoint.jsとCSSでスクロールして画面指定位置で要素をアニメーションさせる

waypoint.jsとCSSでスクロールして画面指定位置で要素をアニメーションさせる

前回「アニメーションが心地良いWebサイト11選」という記事でアニメーションを取り上げました。

今回は実装編をやってみようと思います。その中でも今回は「ボックススライドイン」のアニメーションをやります。(※ボックススライドインという名称は私が勝手にそう呼んでいるだけです。)

表題のとおり、waypoint.jsとCSSで比較的簡単にスクロールして画面指定位置で要素をアニメーションさせることができます。

まずはサンプルをご覧ください。

waypoint.jsを設置

画面の指定位置に要素が入ったことを取得するためwaypoint.jsを使用します。スクリプトを自前で書いて行うこともできますが、waypoint.jsスクロールのアップ・ダウンを判別できたりとても便利なプラグインなので使用していきましょう。

「Download」をクリックして一式をダウンロードします。
いくつかファイルがありますが、今回は「lib」フォルダの中の「jquery.waypoints.min.js」を使用します。

では設置をしていきます。

<script type="text/javascript" src="/js/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="/js/jquery.waypoints.min.js"></script>

<head>内にてwaypointを読み込みます。今回はjQueryバージョンのwaypointを使用しているので、jQueryもwaypointの前に読み込みます。(ファイルまでのパスは適宜変更してください。)

要素が画面指定位置に来たタイミングを取得してクラスを付与

設置ができたら要素が画面指定位置に来たタイミングを取得しましょう。

まずはコードを見ていきましょう。コードは該当箇所に絞っています。

HTMLのコードです。

<div class="animation-box">
    <h2>Section1</h2>
    <p>このボックスが画面上から70%の位置に来たら背景色を変更します。</p>
</div>

このあとjQueryで「animation-box」が画面指定位置に来たらクラスを付けます。

jQueryのコードです。

$(function(){
    $('.animation-box').waypoint(function(direction){
        var activePoint = $(this.element);
        if (direction === 'down') { //scroll down
            activePoint.addClass('active');
        }
        else{ //scroll up
            activePoint.removeClass('active');
        }
    },{offset : '70%'});
});

2行目、functionの引数に「direction」を指定することで下方向へのスクロールか上方向へのスクロールか判別することができます。ここがwaypointの便利なところです。

3行目「animation-box」が複数ある場合でも「var activePoint = $(this.element);」で現在の画面指定位置に来た要素を変数「activePoint」に代入しています。これを設定しないと対象の要素が複数ある場合、まだ画面指定位置に来ていない要素にも一気に適用されてしまいます。

4行目「if (direction === 'down')」で下方向のスクロールかつ要素が画面指定位置に来たタイミングで「active」というクラスを付けています。逆に上方向へのスクロールで要素が画面位置に来たら「active」クラスを外して元に戻しています。

10行目「offset : '70%'」が画面位置の指定になります。この場合、画面の上から70%のところということになります。「offset : ‘50%’」なら画面の縦中央になります。

CSSでアニメーションさせる

CSSのコードです。

.animation-box:nth-child(odd){
    background: #eee;
}
 
.animation-box{
    padding: 120px;
    transition:.5s;
}
 
.animation-box.active{
    background: #666;
    color: #fff;
}

デフォルトのanimation-boxのスタイルに「transition: .5s;」を設定して0.5秒でアニメーションするようにしています。そして画面指定位置に来たら付与されるクラスのスタイル「.animation-box.active」で背景色とフォントカラーを変更しています。

タイミングを取得して簡単なアニメーションをさせるサンプル

わかりやすいようにボックスの背景色を変えていますが、大事なのはそこではなく、画面指定位置に来たタイミングでクラスを付与している点です。これさえできればあとはCSSで色々アニメーションさせることができます。

おさらいです。

  1. waypoint.jsを設置
  2. 要素が画面指定位置に来たタイミングを取得してクラスを付与
  3. CSSでアニメーションさせる
  4. 応用編

では次はちょっとした応用をやっていきます。

応用編

まずはHTMLのコードです。

<section class="sec">
    <div class="flex">
        <figure class="img-container col2">
            <img class="img-container__img" src="images/img01.jpg" alt="img01">
        </figure>
        <div class="text-container col2">
            <h2 class="text-container__title">SECTION01</h2>
            <p>
            今回はwaypoint.jsで「offset:70」を設定していますので、画面上から70%位置まで要素が来るとイベントを発生させることができます。<br>
            そして発生したイベントで要素に「active」というクラスをつけて、
            </p>
        </div><!--text-container-->
    </div><!--flex-bet-->
</section>

3行目、6行目「img-container」と「text-container」の2つがアニメーションさせる要素になりますので、画面指定位置に来たらjQueryで「active」クラスを付けます。

次にCSSのコードです。

.sec{
    margin-bottom: 120px;
}
 
.flex{
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}
 
.col2{
    width:40%;
}
 
.img-container{
    overflow: hidden;
    position: relative;
}
 
.img-container__img{
    display: block;
    opacity: 0;
    position: relative;
    transition:all .5s .3s ease; 
    z-index: 0;
}
 
.img-container:before{
    background: #333;
    content: '';
    display: block;
    height: 100%;
    position: absolute;
    transform: translateX(-100%);
    transition:all .8s 0s ease; 
    width: 100%;
    z-index: 1;     
}
 
.text-container{
    opacity: 0;
    padding:0 60px;
    transition: all .8s .5s ease;
}
 
.text-container__title{
    color: #333;
    font-size: 60px;
    font-weight: 700;
}
 
/*アニメーションするプロパティを設定します*/
.img-container.active img{
    opacity: 1;
}
 
.img-container.active:before{
    transform: translateX(100%);        
}
 
.text-container.active{
    opacity: 1;
}

img-container」と「text-container」の2つは、CSSのflexコンテナーで横並びにしています。
22行目「img-container」に「overflow: hidden;」を指定し、はみ出した要素を見えなくします。

スライドインするボックスは「img-container」のbefore擬似要素で設定しています。
そして40行目「transform: translateX(-100%);」で左側の見えない位置に配置しています。

img-container__img」と「text-container」はアルファをアニメーションさせるので「opacity: 0;」にしておきます。(28行目、47行目)

また、全て同時にアニメーションさせず、ずらしたいので「img-container__img」は「transition:all .5s .3s ease; 」で0.3秒遅らせて、「text-container」は「transition: all .8s .5s ease;」で0.5秒遅らせています。(41行目、49行目)

これで、画面指定位置に要素が来ると「active」クラスが付与されて、

  1. img-container」のbefore擬似要素がアニメーションスタート
  2. img-container」内の「img-container__img」が0.3秒遅れてアニメーションスタート
  3. text-container」が0.5秒遅れてアニメーションスタート

となります。

この何秒かけてアニメーションさせるか(duration)、何秒遅らせてアニメーションさせるか(delay)、アニメーションのイージング(timing-function)といった設定がセンスを問われるところです。不自然ではなく、見ていて気持ちいい感覚を身につけましょう。

最後にjQueryのコードです。

$('.img-container').waypoint(function(direction){
    var activePoint = $(this.element);
    //scroll down
    if (direction === 'down') {
        activePoint.addClass('active');
    }
    else{
        activePoint.removeClass('active');
    }
},{offset : '70%'});
 
$('.text-container').waypoint(function(direction){
    var activePoint = $(this.element);
    //scroll down
    if (direction === 'down') {
        activePoint.addClass('active');
    }
    else{
        activePoint.removeClass('active');
    }       
},{offset : '70%'});

jQueryはやることは特に変わりません。「img-container」と「text-container」に同じくクラスを付与する設定をしました。

最後にもう少し要素を細かくアニメーションさせてみました。

まとめ

やり方さえわかればそれほど難しくありませんので、まずは簡単なアニメーションで動きを確認し、慣れて来たらアニメーションさせるプロパティーを変えてみたりdurationやdelayで続けてアニメーションさせてみたりするとバリエーションが増えていくと思いますのでぜひ色々試してみてください。

Category&Tag