【映える!?】GSAPでピン留めされた画像が出現するスクラブアニメーション

りょーすけ
りょーすけ

Appleサイト風のお洒落なアニメーションないの??

GSAP MAN
GSAP MAN

GSAPのScrollTrigger使ったら良さげなのできるよ~!

スクロールに応じた逆再生も可能なスクラブアニメーション

最近はユーザーのアクションに応じたインタラクティブなサイトが増えてきた印象があります

手軽にインタラクティブな機能を実装してくれるのがGSAPです。GSAPには様々なプラグインがあるのですがその中でもScrollTriggerを使いながら【映える】アニメーションを作ってみましょう

デモ

まずはこちらのデモをご覧ください。

スクロールするごとに複数画像が見えてくると思います

See the Pen pinned-gallery-scroll-to-view by りょーすけ (@s_ryosuke_1242) on CodePen.

HTML

まずはHTMLを見てみましょう。

特に注意点はなく画像を並列に8つ配置しており4つのfigureタグにクラス名.centerを付与しています

<main>
    <div class="container">
        <figure><img src="https://picsum.photos/1440/1440/?random=1" alt=""></figure>
        <figure><img src="https://picsum.photos/1440/1440/?random=2" alt=""></figure>
        <figure><img src="https://picsum.photos/1440/1440/?random=3" alt=""></figure>
        <figure class="center"><img src="https://picsum.photos/id/64/1440/1440" alt=""></figure>
        <figure><img src="https://picsum.photos/1440/1440/?random=4" alt=""></figure>
        <figure><img src="https://picsum.photos/1440/1440/?random=5" alt=""></figure>
        <figure><img src="https://picsum.photos/1440/1440/?random=6" alt=""></figure>
        <figure><img src="https://picsum.photos/1440/1440/?random=7" alt=""></figure>
    </div>
</main>

CSS

次にCSSです。デモからもわかるようタイル状に要素が配置されるようにdisplay:grid;を用いてスタイルを適用しております

figureタグのクラス名.centerが付与された要素以外はopacity:0; visibility:hidden;で非表示にしておきます

この理由は後ほど説明します

*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

main{
    overflow: hidden;
    background-color: #333;
}
.container{
    max-width: 1024px;
    width: 100%;
    height: 100%;
    padding: 1000px 20px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: repeat(4,1fr);
    grid-template-rows: repeat(6,1fr);
    gap: 30px;
}
img{
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 5px;
}
figure:nth-of-type(1){
    grid-column: 1/2;
    grid-row: 3/4;
}
figure:nth-of-type(2){
    grid-column: 2/3;
    grid-row: 2/3;
}
figure:nth-of-type(3){
    grid-column: 3/4;
    grid-row: 1/3;
}
figure:nth-of-type(4){
    grid-column: 2/4;
    grid-row: 3/5;
}
figure:nth-of-type(5){
    grid-column: 2/3;
    grid-row: 5/6;
}
figure:nth-of-type(6){
    grid-column: 3/4;
    grid-row: 6/7;
}
figure:nth-of-type(7){
    grid-column: 4/5;
    grid-row: 2/3;
}
figure:nth-of-type(8){
    grid-column: 4/5;
    grid-row: 4/5;
}

figure:not(.center){
    opacity: 0;
    visibility: hidden;
}

JavaScript

次にJavaScriptです。今回はScrollTriggerを用いるため忘れずにCDNによるダウンロード等を行ってください。

// ScrollTrigger登録 なくても良いがある方が推奨されている
gsap.registerPlugin('ScrollTrigger');
// タイムラインが発動するトリガー等を設定
// from scale 4:4倍の大きさから
// to scale 1:通常の大きさへ
gsap.fromTo('.container',{scale:4},{scale:1,
    scrollTrigger:{
        trigger:'.center',// アニメーションが発火するトリガー要素
        start:'center center',// .center要素の上下中央(center)が画面上下中央(center)に差し掛かったら
        scrub:1,// スクラブアニメーション 数値で慣性を制御
        pin:'.container',// ピン留めする要素
        onEnter:()=>{// アニメーション発火位置に到達したら
            gsap.set('figure:not(.center)',{autoAlpha:1})// .center要素以外のfigure要素の表示
        },
        onLeaveBack:()=>{// アニメーション発火位置に下から戻ってきたら
            gsap.set('figure:not(.center)',{autoAlpha:0})// .center要素以外のfigure要素の非表示
        },
    }
})

各行にコメント文を記載しているので一つ一つ追っていけば理解ができるかと思います

あらかじめ.center以外を非表示にしていた理由

.centeropacity:0; visibility:hidden;を外した状態でデモをご覧いただけると一目瞭然かと思います

See the Pen pinned-gallery-scroll-to-view–visible by りょーすけ (@s_ryosuke_1242) on CodePen.

拡大表示された2枚の画像が見えてしまっていますよね?

上記のcodepenとデモのコードと違う箇所は

cssの61行目~64行目

JSの12行目~17行目

コールバック関数のonEnterとonLeaveBack

あらかじめ非表示にしているということは再び表示させる必要があるわけなのですがそれはJSの12行目~17行目にて制御しております

onEnterアニメーション発火位置に到達したら

onLeaveBackアニメーション発火位置に下から戻ってきたら

呼び出される関数です。英単語の意味を知っているとイメージしやすいですよね

また()=>の形を見ても分かるようにアロー関数になっておりますので中括弧{}の中身は好きにJSの記述が可能です

{ ま★じ★で★優★秀★す★ぎ★る (//ω照♥ }

まとめ

いかがだったでしょうか。

GSAPのScrollTriggerを使用してたった数行による記述だけでお洒落な映えるインタラクティブでエクセレントなスクラブアニメーションが完成しました✨(カタカナ多い…笑)

毎回記事でもお話しているかもですが、とにかくGSAPはコールバック関数が優秀過ぎます。Swiper並みに

オプションが複雑で難しく感じるかもしれませんがその分表現の幅が広がるということでもあります。

ぜひご自身の手でも実現したいアニメーション実装に向けて熟考してドキュメント見ながら取り組んでみてください

最後までご覧いただきありがとうございました!またね~!