【初心者向け】CSSとJavaScriptで基本的なアニメーション付与方法【GSAP使用】

今回はJavaScriptのアニメーションライブラリ『GSAP』を用いてより実践的なアニメーション付与の方法を解説します。

私が所属しているコミュニティ内で以前、ライブコーディングを開催させていただいた際のものを使用します。

今から差別化したポートフォリを作成したい!と思っている方やGSAPって実際どんな感じ?と思っている方には参考になる記事となってます。

コピペしてすぐに実装できるようにCodePenによるデモを用意しています。ぜひ最後までご覧いただけると嬉しいです。

「解説はいらないからコードだけ見せて!」っていう場合は2.完成後のイメージをご覧ください~

1.参考サイト

使用するコードは作って学ぶコーディング学習サイト「Codestep」様を参考にさせていただきました。

デザインはごく一般的なグレーを基調としたコーポレートサイトとなっています。この状態でも洗練されていて素晴らしいのですがアニメーションをつけることでより魅力的なサイトに仕上げることができます。

制作会社から「既にコーディングされたページに効果的なアニメーションとこちらから提示する参考サイトを元にアニメーション付与してください」というご依頼を想定として行っていきます。

主なセクション
  • ヘッダー
  • メインビジュアル
  • NEWS
  • ABOUT
  • BUSINESS
  • COMPANY
  • フッター

ざっくりとですが以下の画像のような模擬指示書を元にアニメーションをつけていきます。

ソースコードがダウンロードできたら早速始めていきましょう!

2.完成後イメージ

完成後のイメージは以下の通りです。
右上の「EDIT ON CODEPEN」からご覧いただけます

See the Pen gsap coding demo by りょーすけ (@s_ryosuke_1242) on CodePen.

アニメーション実装前と比べると格段に魅力的なページに仕上がっていますね✨
画像はphotoACから引っ張ってきています。

模擬指示書に書かれている動きの参考サイトはそれぞれ株式会社リチカ様起業家育成高等学院様です。

3.GSAP導入・リセットcss

実装前の注意点としては予め、CDNでプラグインをダウンロードしておきましょう。
CDNはコチラ
必要なファイルは『gsap.min.js』『ScrollTrigger.min.js』です。

GSAPの導入方法は以下の記事からご覧ください

【高機能】アニメーションライブラリ GSAPの使い方 – おすすめ導入方法はCDN

またリセットcssは最小限のデスタイルをしてくれるress.cssを使用しています。
CDNはこちら

4.オープニングアニメーション

ではオープニングアニメーションから順に記述内容を見ていきましょう!

3行目はこのあと使用するScrollTriggerプラグインを登録しています。

重要なところは6-12行目。

See the Pen オープニングアニメーション by りょーすけ (@s_ryosuke_1242) on CodePen.

6行目のgsap.timeline()で連続するアニメーションの管理ができるようになります。
括弧の中に記述されているdelay:.2は0.2秒アニメーション開始を遅らせます

JavaScriptの特徴でもあるメソッドチェーンをGSAPも踏襲しており時系列順にTween(トゥイーン)を記述することで理想のアニメーションが実現できます。

Tweenについての詳細はGreenSock公式サイトからご覧ください。
アニメーションの最小単位と覚えればとりあえずは問題ないです。

const openingTL = gsap.timeline({delay:.2});//0.2秒遅れて連続アニメーション開始

8行目は.to()メソッドを使用してメインビジュアル画像を1.2秒かけて不透明度を100%にする処理を行っています。

autoAlphaはcssプロパティでいうopacityとvisibilityの2つを組み合わせたものでレンダリングの問題でautoAlphaを使用することが推奨されています。

durationでアニメーションの秒数を指定することが可能です。

.to('#mainvisual img',{autoAlpha:1,duration:1.2})//1.2秒かけて不透明度を100%に

9行目は.set()メソッドを使用して画像にかけている黒色半透明のマスクを不透明度100%にする処理を行っています。
8行目の.to()プロパティとの違いは.set()は瞬時に状態を設定します。よって.set()はアニメーションというよりかは状態設定として考えるとしっくりくると思います。

また注目していただきたいのが最後の括弧直前に記述されている不等号「'<‘」これはgsap.timeline()独特の記法で直前のTweenと同時にアニメーション開始という意味があります。
逆に記号が反対の「’>’」は直前のTweenが終わった直後に開始となります。
数学と同じ大小関係で考えると覚えやすいと思います。

.set('#mainvisual .mask',{autoAlpha:1},'<')//直前のTweenと同時に不透明度100%に状態設

10行目はメインビジュアルのh2タグを1秒かけて{大きさ1.1倍,不透明度0%}から{大きさ1倍,不透明度100%}にする処理を行っています。
8,9行目と違い今回は.fromTo()メソッドが使用されています。これはある状態からある状態へと変化させるもの使用頻度も高いです。

先程と違い不等号「'<‘や’>’」が書かれていませんがその場合はデフォルトで直前のTweenが終わった直後にアニメーション開始つまり「’>’」がデフォルトで設定されます。

11行目は10行目はさほど変わりません。違う点は大きさが1.2倍の状態から1倍に変化させる点のみです。

最後に12行目はヘッダーを上から元の位置に1秒かけて移動する処理となっています。gsapにおけるyプロパティはcssに置き換えると

 .fromTo('#header',{y:'-100%'},{y:'0%'})//1秒かけてヘッダーの要素高さ分、上から元の位置に降りてくる

5.スクロールに応じてセクションが広がる

次にスクロールに応じてセクションを広げる方法をご紹介します。

gsap.fromTo('.top-container',{scaleX:.925},{scaleX:1,ease:'none'})

メソッド.fromTo()によって、大きさ0.925倍から等倍に変化させるように指示しています。

また加減速easeは’none’。つまり、リニアに変化するように指定しています。

しかし、このままでは「スクロールに応じて」アニメーションを進めるということが実現できません。そこで以下のようにScrollTriggerを組み込みます。

gsap.fromTo('.top-container',{scaleX:.925},{scaleX:1,ease:'none',
  scrollTrigger:{
    trigger:'#mainvisual',
    start:'bottom bottom',
    endTrigger:'.top-container',
    end:'top top',
    scrub:true,
  }
})

scaleやease、opacityなどのプロパティと同様に「scrollTrigger」というプロパティを加えてあげます。先頭が小文字になっているので注意です。

scrollTriggerの各プロパティの意味
  • triggerはアニメーションを発火させる要素。
  • startはtrigger要素のtopがwindowのbottomに到達したときに発火スタート
  • endTriggerはアニメーションを終了のきっかけを与える要素
  • endはendtrigger要素のbottomがwindowのtopに到達したときにアニメーション終了
  • scrubはスクロールに応じてアニメーションを進行させる
gsap.fromTo('.top-container',{scaleX:.925},{scaleX:1,ease:'none',
  scrollTrigger:{
      trigger:'#mainvisual',
      start:'bottom bottom',
      endTrigger:'.top-container',
      end:'top top',
      scrub:true,
  }
})

6.パララックス

次にパララックスですがScrollTriggerを使えば簡単に実装が可能となってます。

ScrollTrigger.matchMedia({
  "(min-width:900px)":function(){
      gsap.fromTo('#about img',{y:100},{y:-100,
          scrollTrigger:{
              trigger:'#about img',
              start:'top 80%',
              end:'bottom 20%',
              scrub:2,
          }
      })
  },
  "(max-width:899px)":function(){
      gsap.fromTo('#about img',{y:100},{y:0,
          scrollTrigger:{
              trigger:'#about img',
              start:'top 80%',
              end:'bottom 20%',
              scrub:2,
          }
      })
  },
});

ここで使用しているScrollTrigger.matchMediaですがこれはデバイス幅に応じてアニメーションを変更させることが可能となっています。

つまり上記の場合900px以上の場合はy軸の100pxから-100pxへ移動。899px以下ではy軸の100pxから0pxに移動という記述になっています。

またscrubの値を変更させることで慣性する度合いを変化させることができます。

7.時間差でフェードインアップ

時間差でフェードインアップも大して難しい実装ではありません。

いきなり時間差を目指して実装するのではなくまずはフェードインアップだけの記述を以下に示します。

gsap.fromTo('#business .item',{autoAlpha:0,y:25},{
  autoAlpha:1,y:0,
  scrollTrigger:{
      trigger:'#business',
      start:'top 12%',
      toggleActions:'play none none reverse',
  },
})

内容としては不透明度0%、y軸方向25px下から不透明度100%、y軸方向0px(元の位置)にアニメーションするといったものになっています。

また見慣れないプロパティtoggleActionsに関しての実例はこちらのcodepenからご覧いただけます。

今回の場合’play none none reverse’はtrigger要素がスタート位置に達した時に’play’、アニメーション終了位置に下から入ったときにアニメーションの逆再生となっています。

これでフェードインアップのみの実装が可能となります。このあとに時間差の機能を付与したいと思います。そこで以下のように4行追加します。

gsap.fromTo('#business .item',{autoAlpha:0,y:25},{
  autoAlpha:1,y:0,
  stagger:{
      each:.2,
      from:'start',
  },
  scrollTrigger:{
      trigger:'#business',
      start:'top 12%',
      toggleActions:'play none none reverse',
  },
})

追加されたのは3~6行目の部分です。eachが時間差の秒数。fromがアニメーションを開始させる要素の順番を指定することができます。他にもcenterやendなどがあるのでぜひお試しください。

8.ワイプ

最後にワイプ表現の実装を紹介します。

const companyAnimationTL = gsap.timeline();
companyAnimationTL
.fromTo('#company .mask',{x:'100%'},{x:'-100%',duration:.8,ease:'power2.inOut'})
.set('#company img',{autoAlpha:1},'<+.4')
ScrollTrigger.create({
  trigger:'#company',
  start:'top center',
  animation:companyAnimationTL,
})

今までと同様にscrollTriggerを使用しているのですが違う所が一点。ScrollTrigger.crate()

これのメリットとしてはプロパティanimationでタイムライン.timeline()を使用するという点があります。

今回作成したタイムラインcompanyAnimationTLは以下の画像のようなイメージになってます。

ワイプ表現のイメージ-GSAP

これでcompanyセクションが画面内に入った時にワイプ表現が発火されるようになりましたね!

9.最後に

今回は既にコーディングされたWebページにアニメーション付与してより魅力的なサイトに仕上げる挑戦をしました。

紹介したアニメーションは全てcssとjQueryでも不可能な実装ではございません。しかしgsapを使用することで比較的少なめの行数で簡単にアニメーションを実現することができるようになります。

ぜひぜひ皆さんも本記事を参考に触ってみてください。最後までご覧いただきありがとうございました!