【CSS + JS】テキストの無限ループアニメーション
lax.jsの使い方
【スクロール連動アニメーションの実装】
目次
lax.jsとは
スクロールに合わせて様々なアニメーションを付与できるJSライブラリです。
スクロールに合わせたスムーズなアニメーション効果が特徴でめちゃくちゃいい感じでにヌルヌル動いてくれます。コード自体は4.4KBほどの軽量スクリプトとなっており、既存のサイトに取り入れるのも簡単。PC・スマホどちらでも動きます。jQueryなど他ライブラリへの依存もなく、VueやReactのプロジェクトでも使えるようです。
公式のデモはこちら↓
公式のGitHubはこちら↓
alexfoxy/lax.js
https://github.com/alexfoxy/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プロパティの一覧になります。
プロパティ名 | 内容 |
---|---|
opacity | opacity |
scaleX | transform:scaleX(); |
scaleY | transform:scaleY(); |
scale | transform:scale(); |
skewX | transform:skewX(); |
skewY | transform:skewY(); |
skew | transform:skew(); |
rotateX | transform:rotateX(); |
rotateY | transform:rotateY(); |
rotate | transform:rotate(); |
translateX | transform:translateX(); |
translateY | transform:translateY(); |
translateZ | transform:translateZ(); |
blur | filter: blur(); |
hue-rotate | filter: hue-rotate(); |
brightness | filter: 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'],
//...
]
}
},
という感じでelInY
とelOutY
を使えばOKです。
演算子を使って計算もできるので、細かな調整も効きます。
下記は要素が画面に入る200px手前からアニメーションを開始して、200px画面外から出た時に終わるように設定した場合
{
scrollY: {
translateX: [
['elInY-200', 'elOutY+200'],
//...
]
}
},
このように決まった値を取得できるタグの一覧は下記になります。
タグ | 値 |
---|---|
screenWidth | 画面の幅 |
screenHeight | 画面の高さ |
pageWidth | ページ全体の幅 |
pageHeight | ページ全体の高さ |
elWidth | 指定した要素の幅 |
elHeight | 指定した要素の高さ |
elInY | 要素が画面下部から入る時の縦スクロール位置 |
elOutY | 要素が画面上部から出る時の縦スクロール位置 |
elCenterY | 要素が画面の高さの中央に到達した時の縦スクロール位置 |
elInX | 要素が画面右側から入る時の横スクロール位置 |
elOutX | 要素が画面左側から出る時の横スクロール位置 |
elCenterX | 要素が画面の幅の中央に到達した時の横スクロール位置 |
index | lax.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
パララックス風にスクロールと逆方向に動きながら左右にぐにゃっと歪むようなアニメーションになりました。
アニメーションのオプション
いくつかあるのですが、ここではeasing
とcssFn
についてだけ紹介します。
その他の慣性(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-position
やbackground-size
などですかね。こういったオプションがあると助かります。
プリセットアニメーションを使う場合
lax.jsにはhtmlのclassに指定するだけでプリセットで使えるアニメーションが用意されています。
<div class="lax lax_preset_fadeIn:50:100 lax_preset_spin"></div>
こんな感じで指定すると、スクロールに合わせて要素が回転しながらフェードインします。
プリセットアニメーション用のアプリケーションが公式で公開されているので、ほんとにサクッと使いたい人はこちらを使うのがかなりおすすめです。
アプリケーションの使い方はほぼ説明不要だと思いますが、一応簡単に書いておきます。
左側メニューでチェックを入れたアニメーションが右側のプレビューに表示されます。
ぽちぽちして気に入ったら、左側メニュー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
について過去に記事を上げてますのでこちらもご参考までに。
ひとまず今回はここまで。
RELATED
NEW POSTS
【WordPress】GA4連携の人気記事ランキング機能を自作プラグイン化してみた
【netlify】ビルドイメージを更新 [ Ubuntu Xenial 16.04 → Ubuntu Focal 20.04 ]
【PHP】Google Business Profile APIを使ってクチコミを取得する
スクリーンショットのAPI「screendot」を使ってみた
【window.matchMedia】メディアクエリでhoverが使えるデバイスを判定
DartSassがなかなか辛かったのでGulpを修正してみた