【ScrollMagic】スクロールに応じてclassを付与しcssでアニメーション【ES6】

webサイトを閲覧していてスクロールに反応して要素がフェードインしてくるなどのアニメーションを見たことがありませんか?

今回の記事では僕が実際に案件で使用しているスクロールに反応するアニメーションの実装方法をご紹介していきます。

今回実装するもの

  • 特定の要素が画面内に入ってきたらそれにis-animatedclassを付与
  • is-animatedclassが付与されたらその要素をcssでアニメーションさせる

上記2点です。シンプルですね!
アニメーションに使用するcssは主にtransitionもしくはanimationとなります。

注意事項

  • ES6を使用するためWebpack+Babelなどのコンパイル環境推奨
  • cssにscssの記法があります

サンプル

実装のサンプルです

htmlとcssを用意

htmlとcssを下記のものとします

※今回使用するhtmlとcssはサンプルなので各自書き換えてください。

html

アニメーションさせたい要素にjs-scrollAnimationclassを付与しておきます。

<div class="l-wrapper">

  <div class="l-section js-scrollAnimation">
    <p class="c-text">セクション1です。</p>
  </div>

  <div class="l-section js-scrollAnimation">
    <p class="c-text">セクション2です。</p>
  </div>

  <div class="l-section js-scrollAnimation">
    <p class="c-text">セクション3です。</p>
  </div>

  <div class="l-section js-scrollAnimation">
    <p class="c-text">セクション4です。</p>
  </div>

</div>

css(scss)

js-scrollAnimationが画面内に入ってきたら1.5秒でフェードインしてくるcssです。

.l-wrapper {
  max-width: 700px;
  width: 100%;
  margin: 0 auto;
}

.l-section {
  height: 600px;
  background: #ccc;
  margin-bottom: 30px;
  opacity: 0;
  transform: translate3d(0, 100px, 0);
  transition: opacity 1.5s, transform 1.5s;
  &.is-animated {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

.c-text {
  text-align: center;
}

スクロール用ライブラリ「ScrollMagic」を読み込み

ここからは最重要であるjavascriptの解説をやっていきます。
今回の方法にはScrollMagicというライブラリを使用します。

ScrollMagicとはスクロールに応じて何かをする為のライブラリです。
ScrollMagic公式

CDN(scriptタグ)の場合

<script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/ScrollMagic.min.js"></script>

NPMの場合

npm install scrollmagic
import ScrollMagic from "scrollmagic";

classを付与するスクリプトを記述

使いまわし出来るようにES6のクラス構文で記述してます。

class ScrollAddClass {

  //初期値を設定
  constructor() {
    this.controller = new ScrollMagic.Controller();
    this.settings = {
      target: ".js-scrollAnimation",//アニメーションさせたい要素
      addClassName: "is-animated",//アニメーションさせたい要素に付与するclass
      triggerHook: "onEnter",//発火タイミング:画面下"onEnter"、画面中央"onCenter"、画面上"onLeave""
      offset: 0//100だと100px早く発火-100だと-100px遅く発火
    }
  }

  //実行
  init(options) {
    this.setup(options);
    this.attachEvent(this.controller);
  }

  //外部から入力された設定をマージ
  setup(options) {
    this.settings = Object.assign({
      target: this.settings.target,
      addClassName: this.settings.addClassName,
      triggerHook: this.settings.triggerHook,
      offset: this.settings.offset
    }, options || {});
  }

  //ScrollMagicを実行
  attachEvent(controller) {
    let targets = document.querySelectorAll(this.settings.target);
    if (targets.length == 0) {
      return;
    }
    for (let target of targets) {

      let scene = new ScrollMagic.Scene({
        triggerElement: target,
        triggerHook: this.settings.triggerHook,
        offset: this.settings.offset
      })
        .addTo(controller);

      scene.on('enter', () => {
        target.classList.add(this.settings.addClassName);
      });

    }
  }
}

スクリプトを実行

let scrollAnimation = new ScrollAddClass();
scrollAnimation.init();
  1. new演算子を使用しインスタンスを作成
  2. 作成したインスタンスのinitメソッドを実行

以上でjs-scrollAnimationclassが付いた要素が画面内に入って来るとそれにis-animatedクラスを付与します。
あとはcssでアニメーションさせてください。

オプション

下記のようにinitメソッドの第一引数にオプション用のオブジェクトを渡すことでclassを付与したい要素の変更やそのタイミングを変更できます。

scrollAnimation.init({
  target: '.js-hoge',
  addClassName: "is-hoge",
  triggerHook: "onCenter",
  offset: 100
});

詳細

プロパティ デフォルト 説明
target ".js-scrollAnimation" classを付与したい要素
addClassName "is-animated" targetに付与するclass ※.(ドット)を付けないで記述
triggerHook "onEnter" classを付与するタイミング
"onEnter":targetが1%でも表示されたら
"onCenter":targetが50%表示されたら
"onLeave":targetが100%表示されたら
offset 0 classを付与するタイミングの微調整
100だと100px早く発火-100だと-100px遅く発火

おまけ:モジュール化(外部ファイル化)

以上で説明は終わりですが先程のjavascriptをモジュール化して外部から読み込めるようにします。

外部ファイルを作成

ファイル名をここではscrollAddClass.jsとします。

import ScrollMagic from "scrollmagic";

const scrollAddClass = (() => {
  //==================
  //ここに先程のスクリプトを記述
  //==================
  return new ScrollAddClass();
})();

export default scrollAddClass;

作成したファイルをインポートし実行

以下のようにimportします。
/path/to/の箇所は各自パスを合わせてください。

import scrollAnimation from "/path/to/scrollAddClass.js";
scrollAnimation.init();

以上でモジュール化は終わりです。
こうすることでどこからでも今回作成したスクリプトを使用することができます。

最後に

今回ご紹介した方法はスクロールでclassを付与するだけのシンプルなものですが、外部ファイル化やオプションを渡して挙動を変更したかったので少々長くなってしまいました。

また、モジュール化といってもScrollMagicという外部ライブラリに依存しているため使いづらい点もあるかと思います。

今度はjQueryを使用した簡易版などをご紹介できればと思っています。