Vueのカスタムディレクティブでパララックス(視差効果)を実装する

Vuetifyにあるようなパララックスをプラグインを導入せずに実装したのでその際のメモnoteを残します。

カスタムディレクティブを登録

今回はパララックスを実現するためにVueのカスタムディレクティブを使用し、再利用性を高めたものを作ります。こんな感じ:

const app = new Vue({
    el: '#app',
    directives: {
       parallax: {
           inserted(el, binding) {
               el.setAttribute( // 初期状態のスタイル
                   'style',
                   `
                       height: ${binding.value.height};
                       background: url(${binding.value.src});
                       background-size: cover;
                       background-position-y: ${window.scrollY / binding.value.denominator}px;
                   `
               );
               window.addEventListener('scroll', () => {
                   el.setAttribute( // スクロール量に応じて動的に変化するスタイル
                       'style',
                       `
                           height: ${binding.value.height};
                           background: url(${binding.value.src}) center center;
                           background-size: cover;
                           background-position-y: ${window.scrollY / binding.value.denominator}px;
                       `
                   );
               });
           },
       },
    },
});

上記のカスタムディレクティブでは、引数として3つ渡せるようにしています。

1:src:背景の画像のURL
2:height:パララックスを適応させる要素の高さ
2:denominator:パララックスの度合い(良い引数の名前が思いつかなかった...)

要素へカスタムディレクティブを適応

作成したカスタムディレクティブを実際に使うにはこんな感じ:

<div id="app">
    <div v-parallax="{
        src: 'https://marron-web.site/img/bg-masthead.jpg',
        height: '100vh',
        denominator: 2
    }">
        <h1
            style="
                font-size: 5rem;
                position: absolute;
                top: 40%;
                width: 100%;
                color: white;
                text-align: center;
            "
        >SITE TITLE</h1>
    </div>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</div>

もうちょい使いやすいものにカスタマイズできそうですが、今回はここまで。

いいなと思ったら応援しよう!