lax.jsの使い方【スクロール連動アニメーションの実装】

lax.jsの使い方【スクロール連動アニメーションの実装】

lax.jsとは

スクロールに合わせて様々なアニメーションを付与できるJSライブラリです。

スクロールに合わせたスムーズなアニメーション効果が特徴でめちゃくちゃいい感じでにヌルヌル動いてくれます。コード自体は4.4KBほどの軽量スクリプトとなっており、既存のサイトに取り入れるのも簡単。PC・スマホどちらでも動きます。jQueryなど他ライブラリへの依存もなく、VueやReactのプロジェクトでも使えるようです。

公式のデモはこちら↓

lax.js

公式のGitHubはこちら↓

alexfoxy/lax.js

https://github.com/alexfoxy/lax.js

lax.jsの使い方

ここからはコードサンプルを使った具体的な導入方法について。

簡単なデモサイトを使って説明します。

lax.jsのデモ

このデモのGitHubリポジトリはこちら。
※記事で説明に使っているコードとデモのコードは若干異なる場合があります。

inos3910/lax-demo: lax.jsのデモ

https://github.com/inos3910/lax-demo

導入方法

ライブラリを

  • GitHubリポジトリからダウンロードして使う
  • npmやYarnでモジュールを開発環境にインストールして使う
  • CDNを読み込ませて使う

どの方法でもOKです。

npm・Yarnの場合はパッケージをインストール

$ npm i -D lax.js
$ yarn add -D lax.js

JSでインポートして準備完了。

import lax from 'lax.js'

Githhubからダウンロード・CDNの場合は、<script>タグで読み込んで準備完了。

<!-- ダウンロードした場合はファイルへのパスを指定 -->
<script src="path-to-lax.min.js"></script>
<!-- CDNの場合は使いたいバージョンのものを指定 -->
<script src="https://cdn.jsdelivr.net/npm/lax.js@2.0.3/lib/lax.min.js"></script>

この記事ではlax.jsのバージョンはv2.0.3を使います。
これでlax.jsを使う準備ができました。

実装方法

続いてlax.jsを使ってスクロールアニメーションを実装する方法について。

HTML

任意のクラス名を付けた要素を用意します。

<div class="js-lax">lax</div>

ここではjs-laxというクラス名を付けたdivを用意しておきます。

JS

JavaScriptのコードでアニメーションの実行内容を書いていきます。

//ページの読み込みが完了したタイミングで実行
window.onload = function () {
  //lax.jsを初期化
  lax.init()

  // ドライバーを追加する
  lax.addDriver('scrollY', function () {
    return window.scrollY;
  });

  // 要素にアニメーションを紐づける
  lax.addElements('.js-lax', {
    scrollY: {
      translateX: [
      ['elCenterY', 'elOutY'],
      [-300, 300]
      ]
    }
  });
}

これを実行するとデモの1番上のセクションの動きになります。
https://inos3910.github.io/lax-demo/#section-1
laxという文字がスクロールに合わせて左から右へ動いていくような動きです。

内容を細かく見ていきます。

初期化

window.onloadでページの読み込みが完了したタイミングでlax.init()を実行して初期化します。

window.onload = function () {
  //lax.jsを初期化
  lax.init();

}

公式に準じてwindow.onloadを使っていますが、addEventListenerで書いてももちろんOKです。

window.addEventListener('load', function() {
  lax.init();
});

これで初期化はOKです。

フレームワークを使う場合

VueやReactといったフレームワークと合わせて使う場合は、少し注意が必要な様です。
公式GitHubのDOM behavior and usage with Frameworksに書いてあるのでGoogle翻訳してみました。

パフォーマンスを向上させるために、lax.jsは、ページの読み込み時にアニメーション化する要素のリストにインデックスを付けます。 React、Vue、EmberJSなどのライブラリを使用している場合は、最初のwindow.onloadの後に要素を追加している可能性があります。 このため、アニメーション化するDOMにコンポーネントを追加するときはlax.addElementsを呼び出す必要があり、コンポーネントがアンマウントするときはlax.removeElementsを呼び出す必要があります。 ここでReactの例を見つけてください。 他の例は、Vue.jsとAngularでまもなく利用できるようになります。

https://github.com/alexfoxy/lax.js#dom-behavior-and-usage-with-frameworks

window.onloadのタイミングでは画面上にすべてのコンポーネントが追加されているかどうかわからないので、フレームワークでコンポーネントを追加する時、削除する時に都度関数呼び出して使ってねってことですね。

ドライバーの追加

次にドライバーを追加します。
ドライバーには、アニメーションに使う値を設定します。ここに設定した値をlax.jsがいい感じにアニメーションに適した値に変換して使えるようにしてくれます。

今回は縦スクロールに合わせた動きを付けたいので、縦スクロール量をドライバーに追加します。
コードでは下記のようになります。

lax.addDriver('scrollY', function () {
  return window.scrollY; //アニメーションに使いたい値
});

ドライバーの追加はlax.addDriver関数を使います。
第1引数に任意のドライバーの名前(ここではscrollYにしてますが何でもOK)、
第2引数に数値を返す関数を指定します。 ここではスクロールに連動したアニメーションを設定したいのでwindow.scrollYを返すようにします。

この記事ではスクロールに合わせた動きの紹介をしますが、ドライバーを追加することでそれ以外の動きも対応可能です。
例えばマウスカーソル位置の値をアニメーションに使いたい場合は下記のようなドライバを設定します。

document.addEventListener('mousemove', function (e) {
  lax.__cursorX = e.clientX
  lax.__cursorY = e.clientY
}, false)

lax.addDriver('cursorX', function () {
  return lax.__cursorX || 0
})

lax.addDriver('cursorY', function () {
  return lax.__cursorY || 0
})

これはlax.jsの公式デモのうち、Cursor positionというものに書かれているコードの一部です。
mousemoveイベントに合わせて変化するマウスの座標位置をドライバーに設定しています。

ドライバーの機能があることで工夫すれば他にもいろいろな動作に合わせたアニメーションが作れそうですね。拡張性が高いです。まぁでもよく使われるのはスクロールになるとは思いますが。

その他、第3引数でドライバーのオプションが指定できます。

  • inertiaEnabled >> trueにするとアニメーションに慣性を付けることができます。デフォルトはfalse
  • frameStep >> フレームレート(fps)を変更できます。デフォルトは1で、1秒間に60回更新されます。2に設定した場合は1秒間に30回、60に設定した場合は1秒間に1回の更新になります。

第3引数を指定すると下記のようになります。

lax.addDriver('scrollY', function () {
  return window.scrollY;
},
{
  inertiaEnabled : true,  //慣性を付ける
  frameStep : 2 //30fpsに
}
);

ドライバーのオプションは正直かなり調整が難しいです。そもそもデフォルトでいい感じに設定されているので、よほどアニメーションに関してこだわりがある場合以外はあまり使う機会無さそうです。

アニメーションの設定

最後にアニメーションを設定します。

基本的な設定の仕方は下記のようになります。

lax.addElements(
  // 第1引数 セレクタを指定
  '.js-lax', 
  // 第2引数 アニメーションの情報を設定
  {
    scrollY: {
      translateX: [
      ['elCenterY', 'elOutY'],
      [-300, 300]
      ]
    }
  },
  // 第3引数 オプションを設定(省略化)
  {
    style : {},
    elements : [],
    onUpdate : function (driverValues, domElement) {
    }
    }  
);

lax.addElements関数を使って設定します。

第1引数はアニメーションを設定したいセレクタを設定します(ここでは.js-lax)。
第2引数はアニメーションの細かな動きを設定します。

// 第2引数 アニメーションの情報を設定
{
  //ドライバー名
  scrollY: {
    //CSSプロパティ名 
    translateX: [
    //ドライバーの閾値
    ['elCenterY', 'elOutY'],
    //アニメーションさせる範囲の数値
    [-300, 300],
    //アニメーションのオプション
    {}
    ]
  }
},

ここがlax.jsの肝になってくるので各項目を細かく見ていきます。

ドライバー名

lax.addDriverで追加したドライバーの名前をキーとしたオブジェクトを追加します。
ここでは前述で追加したscrollYを追加しています。
他のドライバーのアニメーション設定を追加する場合は、下記のように追加します。

{
  scrollY : {
    //...
  },
  cursorX : {
    //...
  },
  cursorY : {
    //...
  }
},

こんな感じで指定したセレクタに複数のドライバーごとのアニメーションを設定できます。

CSSプロパティ名

アニメーションさせたいCSSプロパティ名をキーにした配列をドライバーのオブジェクトに追加します。
下記はscrollYドライバーにopacityプロパティを追加しています。

{
  scrollY : {
    opacity : [
      //...
    ]
  }
},

複数のCSSプロパティを設定する場合は下記のように追記していきます。

{
  scrollY : {
    opacity : [
      //...
    ],
    translateX : [
      //...
    ],
    scale : [
      //...
    ]
  }
},

ここで唐突にtranslateXとかscaleとか出てきますが、CSSプロパティではtransformなんじゃないの?ってなりますよね。これに関しては、lax.jsでサポートされているCSSプロパティであればこういった省略記法が使えるようになっています。

下記がlax.jsでサポートされているCSSプロパティの一覧になります。

プロパティ名内容
opacityopacity
scaleXtransform:scaleX();
scaleYtransform:scaleY();
scaletransform:scale();
skewXtransform:skewX();
skewYtransform:skewY();
skewtransform:skew();
rotateXtransform:rotateX();
rotateYtransform:rotateY();
rotatetransform:rotate();
translateXtransform:translateX();
translateYtransform:translateY();
translateZtransform:translateZ();
blurfilter: blur();
hue-rotatefilter: hue-rotate();
brightnessfilter: brightness();

アニメーションに使う主要なプロパティはだいたい揃ってる感じですね。

もちろんここに載っているもの以外でもCSSプロパティであれば指定できます。ただし値が複雑な場合は下記のようにcssFnオプションと組み合わせて使う必要が出てくる場合があります。cssFnオプションについては後述します。

{ 
    // ※box-shadowのようにプロパティ名にハイフンが入る場合はクォートでくくる。
  "box-shadow": [
  ["elCenterY", "elOutY"],
  [0, 50],
  {
    cssFn: (val) => {
      return `${val}px ${val}px ${val}px rgba(0,0,0,0.5)`
    }
  }
  ]
}
ドライバーの閾値

CSSプロパティの配列の1つ目に、ドライバーで設定した値をアニメーションとして発火させる開始位置とアニメーションの終了位置の閾値(しきい値)を配列で設定します。

{
  scrollY: {
    translateX: [
    ['開始位置', '終了位置'],
    //...
    ]
  }
},

ここに例えば下記のように設定した場合、

{
  scrollY: {
    translateX: [
    [500, 1000],
    //...
    ]
  }
},

ドライバーにはscrollYを設定しているので、window.scrollYの値が500pxに到達した位置からアニメーションが始まって、1000pxに到達した位置で終わります。

また、アニメーションのキーフレーム的な使い方になるので、下記のように複数の閾値を設定することもできます。

{
  scrollY: {
    translateX: [
    [500, 1000, 1500],
    //...
    ]
  }
},

その他に、絶対値で指定するのは面倒なのでlax.jsには変わりに自動で値を設定できるタグが用意されています。

例えば、要素が画面に入った時にアニメーションを開始して、出た時に終わるように設定したい場合、

{
  scrollY: {
    translateX: [
    ['elInY', 'elOutY'],
    //...
    ]
  }
},

という感じでelInYelOutYを使えばOKです。

演算子を使って計算もできるので、細かな調整も効きます。
下記は要素が画面に入る200px手前からアニメーションを開始して、200px画面外から出た時に終わるように設定した場合

{
  scrollY: {
    translateX: [
    ['elInY-200', 'elOutY+200'],
    //...
    ]
  }
},

このように決まった値を取得できるタグの一覧は下記になります。

タグ
screenWidth画面の幅
screenHeight画面の高さ
pageWidthページ全体の幅
pageHeightページ全体の高さ
elWidth指定した要素の幅
elHeight指定した要素の高さ
elInY要素が画面下部から入る時の縦スクロール位置
elOutY要素が画面上部から出る時の縦スクロール位置
elCenterY要素が画面の高さの中央に到達した時の縦スクロール位置
elInX要素が画面右側から入る時の横スクロール位置
elOutX要素が画面左側から出る時の横スクロール位置
elCenterX要素が画面の幅の中央に到達した時の横スクロール位置
indexlax.addElementsで追加された要素の順番(インデックス)

これだけあればほとんど対応できそうですね。演算子と組み合わせて使えるのが便利です。

アニメーションの値

CSSプロパティの配列の2つ目に、ドライバーの閾値に合わせてアニメーションの値を指定します。

scrollY: {
  translateX: [
  ['elCenterY', 'elOutY'],
  ['elCenterYの位置のtranslateXの値','elOutYの位置のtranslateXの値']
  ]
}

最初に出したサンプルコードの場合、

scrollY: {
  translateX: [
  ['elCenterY', 'elOutY'],
  [-300, 300]
  ]
}

要素が画面の高さの中央までスクロールされたらtransform:translateX(-300px);の位置から、transform:translateX(300px);に向かってスクロール量に合わせてアニメーションを開始、要素が画面上部から出ていく時にtransform:translateX(300px);の位置でアニメーションを終了します。

また、アニメーションの値にもドライバーの閾値のところで紹介したタグが使えるので、下記のような使い方ができます。

lax.addElements('.js-lax-4', {
  scrollY: {
    translateY: [
    ['elInY', 'elOutY'],
    ['-screenHeight/4', 'screenHeight/4']
    ],
    skewX: [['elInY', 'elOutY'], [40, -40]],
  }
});

この場合は、スクロールで要素が画面下部から入ってきた時はtransform:translateY(-画面サイズの4分の1) skewX(40deg);の位置から、transform:translateY(画面サイズの4分の1) skewX(-40deg);の位置に向かってアニメーションを開始、要素が画面上部から出ていく時にtransform:translateY(画面サイズの4分の1) skewX(-40deg);の位置でアニメーションを終了します。

実際の動きは下記。(デモページの5つ目のセクション)

https://inos3910.github.io/lax-demo/#section-5

パララックス風にスクロールと逆方向に動きながら左右にぐにゃっと歪むようなアニメーションになりました。

アニメーションのオプション

いくつかあるのですが、ここではeasingcssFnについてだけ紹介します。
その他の慣性(inertia)の設定とかは難しいのでそのレベルで使いたい方は公式ドキュメントとGitHubでコードの中身を確かめてから使ってみてください。

easing

CSSやJSのアニメーションライブラリでも設定できますが、アニメーションに緩急を付けることができるオプションです。
アニメーションのオプションに下記のように設定します。

lax.addElements('.js-lax', {
  scrollY: {
    translateX: [
    ['elCenterY', 'elOutY'],
    [-300, 300],
    //配列の3番目にオプションオブジェクトを追加
    {
      easing: 'easeInOutQuart' //イージングを設定
    }
    ]
  }
});

下記はlax.jsで使えるイージングの一覧です。

  • easeInQuad
  • easeOutQuad
  • easeInOutQuad
  • easeInCubic
  • easeOutCubic
  • easeInOutCubic
  • easeInQuart
  • easeOutQuart
  • easeInOutQuart
  • easeInQuint
  • easeOutQuint
  • easeInOutQuint
  • easeOutBounce
  • easeInBounce
  • easeOutBack
  • easeInBack

他のアニメーションライブラリなどで広く使われているものと同じなので、他のライブラリで慣れている場合はわかりやすくて使いやすいです。

cssFn

関数として戻り値にCSSの値を返すようにして使うオプションです。
第1引数がドライバーで取得した値(number)、第2引数が指定した要素(DomElement)になります。

CSSプロパティの指定のところで少し紹介しましたが、box-shadowみたいなCSSの値が複雑になるものをアニメーションしたい場合に使えます。

{ 
    // ※box-shadowのようにプロパティ名にハイフンが入る場合はクォートでくくる。
  "box-shadow": [
  ["elCenterY", "elOutY"],
  [0, 50],
  {
    cssFn: (val) => {
      return `${val}px ${val}px ${val}px rgba(0,0,0,0.5)`
    }
  }
  ]
}

他によく使いそうなのはbackground-positionbackground-sizeなどですかね。こういったオプションがあると助かります。

プリセットアニメーションを使う場合

lax.jsにはhtmlのclassに指定するだけでプリセットで使えるアニメーションが用意されています。

<div class="lax lax_preset_fadeIn:50:100 lax_preset_spin"></div>

こんな感じで指定すると、スクロールに合わせて要素が回転しながらフェードインします。

プリセットアニメーション用のアプリケーションが公式で公開されているので、ほんとにサクッと使いたい人はこちらを使うのがかなりおすすめです。

lax.js preset-explorer
https://alexfox.dev/lax.js/preset-explorer

アプリケーションの使い方はほぼ説明不要だと思いますが、一応簡単に書いておきます。

左側メニューでチェックを入れたアニメーションが右側のプレビューに表示されます。
ぽちぽちして気に入ったら、左側メニュー1番下の「Preset code」のところのcopyをクリック。

あとはアニメーションを付けたい任意の要素に

<div class="hoge"></div>

laxというクラス名を追加して、コピーしたコードを貼り付けるだけです。

<div class="hoge lax lax_preset_fadeIn:50:100 lax_preset_spin"></div>

クラス名にlaxを忘れてコピーしたコードだけ貼り付けても動かないのでそこだけ注意です。

デモ

とりあえず試してみました。

https://inos3910.github.io/lax-demo/

公式ほど上手く動かせないですが、簡単な設定で他のアニメーションライブラリではなかなか実現できない動きを付けることができました。

このデモのGitHubリポジトリはこちら。
※記事で説明に使っているコードとデモのコードは若干異なる場合があります。

inos3910/lax-demo: lax.jsのデモ

https://github.com/inos3910/lax-demo

まとめ

こういうスクロール連動形は他のライブラリだとLocomotive Scrollを使ったことがありますが、スマホの調整が難しかった印象です。その点、lax.jsはスマホでもPCでも動きの滑らかさがいい感じですごく気にいりました!

ググってもあまり情報なかったんですが、ドキュメント読んで公式のデモ見たらそこまで難しくない感じでした。
こういったアニメーションを求められた時は簡単に取り入れて使えそうです。特にプリセットのアニメーションは使えそうなものが多いので時短になって助かります。

苦戦したLocomotive Scrollについてもまた時間があれば書いてみて比較してみようかなと思います。
時間があれば。。。笑

他にスクロール・パララックス関連のライブラリとしてRellax.jsについて過去に記事を上げてますのでこちらもご参考までに。

ひとまず今回はここまで。