Nuxt.js + ScrollMagic を使ったスクロールエフェクト(ふわっと要素を表示)



画面を下にスクロールしていくとフワッと画像が表示されるエフェクトを付けたくて ScrollMagic というライブラリを使ったので、その実装方法を書き残しておきます。
今回は Nuxt.js で作った Web アプリケーションに適用したので、Vue.js 用のプラグインを使っています。



*Scroll Magic とは

スクロールの位置に基づいてアニメーションを動作させたり、要素のCSSクラスを変更したりすることができるライブラリです。具体的な動作としては こちらの公式サイト のようなことができます。オプションを指定して様々な動きを付けることができるので、詳しくは公式サイトを参照してください。


*参考



*環境

  • MacOS
  • nuxt 2.8.1
  • vue-scrollmagic 1.2.0


*インストール

今回は Nuxt のプロジェクトで使ったので、Vue用のプラグインvue-scrollmagicを使いました。
プロジェクト配下で下記コマンドを実行してインストールします。
$ npm i vue-scrollmagic --save


*プラグインの追加

pluginsディレクトリ配下にvue-scrollmagic.jsを新規作成し、vue-scrollmagicのプラグインを使えるようにします。
<plugins/vue-scrollmagic.js>
import Vue from 'vue'
import VueScrollmagic from 'vue-scrollmagic'

Vue.use(VueScrollmagic)

nuxt.config.jsに作成したvue-scrollmagic.jsをプラグインとして追加します。
<nuxt.config.js>
...

  /*
   ** Plugins to load before mounting the App
   */
  plugins: [
    {
      src: '~/plugins/vue-scrollmagic.js',
      ssr: false
    }
  ],

...


*エフェクトの追加

ScrollMagic の基本的な使い方としては、controllersceneを定義する必要があります。
  • controller ----- スクロールするコンテナ毎に1つ定義。(縦 or 横 を指定)
  • scene ------ 何がどのスクロールポジションで始まるかといったプロパティと値をオブジェクトで定義。(複数の定義が可能)
そして複数作成したscenecontrollerに追加することで動作します。
具体的には下記のようにsceneを定義し、addSceneを使ってscenecontrollerに追加します。
#trigger1を通過すると#image1の要素がopacity: '1'となり表示されます。

addIndicatorsは画面にトリガーの位置などのヘルプを表示してくれますが、確認ができたら削除します。
今回はvue-scrollmagicのプラグインを使っているので公式サイトとは少し書き方が異なります。

    const scene1 = this.$scrollmagic
      .scene({
        triggerElement: '#trigger1',   // トリガーにする要素ID
        triggerHook: 0.5,  // トリガーの位置
        offset: 100,       // 開始するスクロールの位置
        duration: 300,     // 終了するスクロールの位置
        reverse: false     // 反対方向からのスクロールを制御
      })
      // ↓実行されるアニメーションと、対象の要素IDを指定
      .setTween('#image1', {
        css: {
          opacity: '1'   // 透明だったクラスを不透明にして表示
        }
      })
      // ↓triggerのヘルプ表示
      .addIndicators({ name: 'OK' })

 // controllerに追加
 this.$scrollmagic.addScene(scene1)

triggerElementに指定した ID を通過すると、setTweenで指定したアニメーションが実行されます。
  • triggerHook
    トリガーの位置を指定することができます。(0:上 / 0.5:中央 / 1: 下)
  • offset
    アニメーションを開始する位置を指定します。トリガーからのスクロール位置をpx単位で指定します。
  • duration
    アニメーションを終了する位置を指定します。この値を大きくすると遅く表示されるようになります。

Vueファイルの全体としては下記になりました。
mounted()scrollMagicの記述をします。
アニメーション実行前は画像をopacity: 0にして不透明にしておき、スクロールで通過後にopacity: 1にして表示させています。
<template>
  <div>
    <section>
      // ---- ↓アニメーションを開始するトリガーにIDを付与 ----
      <h2 id="work-trigger" class="section-title effect-fade-side">
        Works
      </h2>
      <div class="article-body works">
        <div class="article-content">
          <p>技術ブログ</p>
          <a
            // ---- ↓アニメーションを追加する要素にIDを付与 ----
            id="work-image"
            href="https://mmtomitomimm.blogspot.com/"
            target="_blank"
          >
            <img src="~/assets/images/blog.png" />
          </a>
        </div>
      </div>
    </section>
  </div>
</template>
<script>
export default {
  mounted() {
    const scene1 = this.$scrollmagic
      .scene({
        triggerElement: '#work-trigger',
        triggerHook: 0.5,
        duration: 300,
        reverse: false
      })
      .setTween('#work-image', {
        css: {
          opacity: '1'
        }
      })
    // ---- ↓ triggerのヘルプを表示 ----
    // .addIndicators({ name: 'OK' })

    this.$scrollmagic.addScene(scene1)
  }
}
</script>
<style  scoped  lang="scss">
...

// ---- ↓ アニメーション実行前のスタイル(非表示にしておく) ----
 #work-image {
   opacity: 0;
 }

...
</style>

スクロールしていくごとに順番に要素を表示するといったことも、トリガーの位置となる要素 ID を変えれば実現することができます。


*所感

初めて使いましたが、概念を理解すれば基本的な動作は簡単にできるようになりました。動きを付けることで見る側が楽しめるので、情報が多い縦長のサイトでも最後までスクロールしてもらえるといったメリットがありそうです。オプション次第では落下するような動作などもできそうなので、色々試して使いこなせるようにしたいと思います。


Previous
Next Post »

人気の投稿