GSAP ScrollTriggerのプロパティ一覧(2023/4)

## はじめに

ScrollTriggerは、GSAPのプラグインの一つで、スクロールベースのアニメーションをささっと作成できる便利なライブラリです。

基本的には簡単に使えるのですが、意外とプロパティがたくさん用意されており、これらを適切に用いることでより効果的にアニメーションを作成できます。
[API Docs](https://greensock.com/docs/v3/Plugins/ScrollTrigger)は割と簡単な英語でまとめられていますが、これをもとに日本語でまとめてみます。(Version3系)

:::note
2023/04/24
`onKill`、`onRefreshInit`、`onUpdate`追加（前者2つはドキュメントの中で見当たらないけど使えた）
:::

## プロパティ一覧（アルファベット順）

### animation

**値形式：Tween | Timeline**

ScrollTriggerによって発火させるアニメーションを指定します。

1つのScrollTriggerにつき1つのアニメーションしか制御できません。
よって、アニメーションを1つのTimelineにまとめるか、必要であれば複数のScrollTriggerを作成することで対応します。

### anticipatePin

**値形式：数**
**デフォルト値：`0`**

大きなセクションやパネルをピン留めする場合、高速でスクロールしたときにピン留めが少し遅れるように見えることがあります。通常は`anticipatePin: 1`で問題ありませんが、値を調整してピン留めを行うタイミングを変えられます。しかし、ほとんどこのプロパティが必要になることはないようです。

### containerAnimation

**値形式：Tween | Timeline**

水平スクロールのコンテナにおいてアニメーションを発火させたい場合に使用します。

水平方向のスクロールを実装したとき、ネイティブなスクロール方向ではないため、ScrollTriggerではそれを検知することができません。そのため、ScrollTriggerに水平方向アニメーションをするコンテナを教えておく必要があります。
注意として、そのコンテナのアニメーションは直線イージングしか使用できません。また、ピン留めとスナップも使えません。
[公式デモ](https://codepen.io/GreenSock/pen/WNjaxKp)
[詳細](https://greensock.com/3-8/#containerAnimation)

### end

**値形式：文字列 | 数 | 関数**
**デフォルト値：`bottom top`**

ScrollTriggerの終了位置を指定します。

これは、ScrollTriggerが作成されたときやリサイズが発生したときに、通常のドキュメントフローにおける位置に基づいて計算される静的な位置であり、常に再計算されるわけではありません。`ScrollTrigger.refresh()`を呼べば、強制的に再計算させることができます。

#### 文字列指定の場合

endTrigger(定義されていない場合はtrigger)の位置と、スクローラーの位置を記述します。
`top`、`bottom`、`center`（`horizontal: true`の場合は`left`、`right`）などのキーワードや、`80%`などのパーセンテージ、`100px`などのピクセル値を使用することができます。パーセンテージやピクセル値は、常に要素／ビューポートの上端／左端を基準にしています。

例：

|オプション|意味|
|:-:|:-|
|`bottom center`|endTriggerの下端がスクローラーの中心に当たった時|
|`center 100px`|endTriggerの中心がスクローラーの上から100px下に当たったとき|
|`+=300`|開始位置から300px下|
|`+=100%`|開始位置からスクローラー分の高さ|
|`max`|スクロール位置の最大値|

#### 数指定の場合

スクロールした分の値となります。
つまり`200`は、スクローラーがちょうど200pxスクロールしたときに発火するということになります。

#### 関数指定の場合

指定した関数は、ScrollTriggerの作成時やスクローラーのリサイズ時、つまり、位置が計算されるたびに呼び出されます。この関数は、文字列もしくは数をリターンしなければいけません。
これを利用することで、動的に値を計算することが容易になります。

### endTrigger

**値形式：文字列 | 要素**
**デフォルト値：`trigger`の値**

ScrollTriggerの終了位置のトリガーとなる要素を指定します。
この値は必ず定義する必要はありません。

### fastScrollEnd

**値形式：真偽値 | 数**
**デフォルト値：`false`**

`true`の場合、スクロール速度が2500px/sよりも速くトリガーエリアを離れたとき、ScrollTriggerのアニメーションを強制的に完了させることができます。
これにより、ユーザが素早くスクロールしたときにアニメーションが重なるのことを防ぐことができます。

数値を指定することで、アニメーションを強制的に完了させるスクロール速度の最小速度を変更できます。
例えば、`fastScrollEnd: 3000`とすることで、スクロール速度が3000px/sを超えた場合にトリガリングします。

### horizontal

**値形式：真偽値**

水平スクロールを使用する場合は`true`を指定します。

### id

**値形式：文字列**

ScrollTriggerインスタンスのidです。これはマーカーにも追加されます。
`ScrollTrigger.getById()`でこの指定したidを読み込むことができます。

### invalidateOnRefresh

**値形式：真偽値**

`true`とすると、ScrollTriggerに紐付けられたアニメーションは、`refresh()`が発生するたびに（通常はリサイズ時）`invalidate()`メソッドが呼び出されるようになります。
`invalidate()`メソッドは、内部に記録されている開始値や終了値を全て消去します。

### markers

**値形式：オブジェクト | 真偽値**

`true`にすると、triggerなどのマーカーが画面に表示されます。
これが開発時やトラブルシューティングの際に非常に有用です。

マーカーのデフォルト設定は以下のようになっていますが、オブジェクトを指定することでカスタマイズが可能です。
`{ startColor: "green", endColor: "red", fontSize: "16px", fontWeigth: "normal", indent: 0 } `

### once

**値形式：真偽値**

`true`の場合、ScrollTriggerが終了位置に到達するとすぐに`kill()`(ScrollTriggerインスタンスをキル)を実行します。正方向へのスクロール時に一度だけアニメーションを実行し、リセットやリプレイをしないようにしたい場合に最適なプロパティです。toggleActionsは自動的に`play none none none`に設定されます。

これにより、スクロールイベントのリッスンを停止し、[ガベージコレクション](https://developer.mozilla.org/ja/docs/Web/JavaScript/Memory_Management#garbage_collection)の対象となります。
これは`onEnter`を1回だけ呼び出すことになります。また、このプロパティを有効にしたものに関連するアニメーションを停止することはありません。

### onEnter

**値形式：関数**

スクロール方向が正で、スクロール位置が`start`を通り過ぎたときのコールバック関数を設定できます。
ScrollTriggerインスタンスの各プロパティやメソッドを受け取ります。

例：

```js
onEnter: ({progress, direction, isActive}) => console.log(progress, direction, isActive)
```

### onEnterBack

**値形式：関数**

スクロール方向が負で、スクロール位置が`end`を通り過ぎたときのコールバック関数を設定できます。
ScrollTriggerインスタンスの各プロパティやメソッドを受け取ります。

### onKill

**値形式：関数**

ScrollTriggerインスタンスが`kill`されたときのコールバック関数を設定できます。

### onLeave

**値形式：関数**

スクロール方向が正で、スクロール位置が`end`を通り過ぎたときのコールバック関数を設定できます。
ScrollTriggerインスタンスの各プロパティやメソッドを受け取ります。

### onLeaveBack

**値形式：関数**

スクロール方向が負で、スクロール位置が`start`を通り過ぎたときのコールバック関数を設定できます。
ScrollTriggerインスタンスの各プロパティやメソッドを受け取ります。

### onRefresh

**値形式：関数**

リフレッシュが発生したときのコールバック関数を設定できます。
ScrollTriggerインスタンスの各プロパティやメソッドを受け取ります。

### onRefreshInit

**値形式：関数**

リサイズが発生した直後、ScrollTriggerがドキュメントフローの開始/終了値の再計算を行う前のコールバック関数を設定できます。

### onScrubComplete

**値形式：関数**

scrubが完了したときのコールバック関数を設定できます。これは、scrubが定義されている場合にのみ有効です。
ScrollTriggerインスタンスの各プロパティやメソッドを受け取ります。

### onSnapComplete

**値形式：関数**

スナップが完了したときのコールバック関数を設定できます。これは、snapが定義されている場合にのみ有効です。
スナップは、何らかの形でスクロールを行った場合にはキャンセルされるので、その場合には`onSnapComplete`は機能しません。
ScrollTriggerインスタンスの各プロパティやメソッドを受け取ります。

### onToggle

**値形式：関数**

ScrollTriggerがinactiveからactiveに、または、その逆に切り替わったときのコールバック関数を設定できます。
通常、スクロール位置が`start`か`end`に移動したときに発火しますが、ユーザーが非常に速くスクロールした場合など、同じ瞬間に両方に移動した場合は、状態が変化せず`onToggle`は発火しません。
ScrollTriggerインスタンスの各プロパティやメソッドを受け取ります。

このコールバックは、他のon系のプロパティの代わりに使うことで、トグルの`isActive`プロパティをチェックするのに使うことになると思います。

### onUpdate

**値形式：関数**

ScrollTriggerの進捗が変わる（スクロール位置が変わる）たびに呼び出されるコールバックです。

`scrub`が数値で設定されている場合、関連するアニメーションはスクロールが停止した後もしばらくスクラブし続けるため、アニメーションが更新されるたびに何かを更新することが目的であれば、ScrollTriggerではなくアニメーション自体にonUpdateを適用することが最善策となります。

### pin

**値形式：真偽値 | 文字列 | 要素**

ScrollTriggerがアクティブになっている間、ピン留めされる要素を指定します。
指定した要素は、残りのコンテンツがスクロールし続けている間、開始位置に固定(ピン留め)されているように見えます。
`pin: true`とすると、トリガー要素がピン留めされます。

ピン留め可能な要素は1つだけですが、必要に応じて複数要素を含むこともできます。

注意すべきことは、ScrollTriggerはパフォーマンス向上のために可能な限り事前に計算され、ピン留めした要素を動かすとこの事前に計算した値が狂ってしまうため、ピン留め要素をアニメーションさせてはいけないということです。
代わりにピン留め要素にネストされた要素であればアニメーションさせることは可能です。

### pinnedContainer

**値形式：文字列 | 要素**

`trigger`/`endTrigger`の要素が、他のScrollTriggerによってピン留めされた要素の内側にある場合、ピン留めされている時間分だけ開始/終了位置がずれてしまいます。
`pinnedContainer`をそのトリガー要素の親要素に設定することで、それに応じてオフセットを計算します。

### pinReparent

**値形式：真偽値**

`true`の場合、ピン留め要素がピン留めされている間、`<body>`に再配置され、先祖要素の設定から解放されるようになります。

ピン留め中に予期しない動作（ピン留め要素が突然移動したり、スクロールに合わせて移動したり等）が発生した場合、おそらく先祖要素に`transform`や`will-change`の指定があり、`position: fixed`の動作を邪魔していると考えられます。これはScrollTriggerの問題ではなくブラウザの問題になります。

ただし、この再配置にはコストがかかるため、これらの不具合を避けるように設計するのがベストです。どうしても避けられない場合にのみ、使用するようにしてください。

注意すべき点として、再配置の影響を受ける入れ子要素に依存したCSSルールがある場合、それらは壊れます。
例えば、以下のようなHTMLと、`p`タグにCSSルールが当てられていたとします。

```html
<body>
  <div class="section">
    <div class="panel">
      <p>lorem ipsum dolor sit amet</p>
    </div>
  </div>
</body>
```

```css
.section .panel p {
  color: white
}
```

`p`タグの親要素である`.panel`要素をこのプロパティで固定した場合、入れ子要素となる`p`タグにはこのCSSルールが適用されません。
なぜなら、`.panel`は`<body>`に固定されるように再配置され、`.section`の中に`.panel`がいないためです。

```html:pinReparentがtrueでピン留めされているとき
<body>
  <div class="panel">
    <p>lorem ipsum dolor sit amet</p>
  </div>

  <div class="section">    
  </div>
</body>
```

そのため、再配置に対応するようにCSSルールを記述する必要があります。

### pinSpacer

**値形式：要素**

通常、ScrollTriggerは内部的にピン留め要素を`<div>`で囲みますが、非常に稀なケースで、ピン留め要素内でiframeを読み込んでいる場合、ウィンドウのリサイズ時などのScrollTriggerの更新時に、iframeも一緒に更新されてしまうことがあります。
そこで、このプロパティを用いることで、スペーサーとして使用する要素を内部的に作成されたものではなく、明示的に指定することができます。
これにより、ScrollTriggerの更新時にスペーサーの追加や削除が行われず、iframeのコンテンツをそのまま維持することができるようになります。

### pinSpacing

**値形式：文字列 | 要素**

デフォルトでは、ピン留め要素がピン留めを解除されたときに後続のコンテンツがちゃんと追いつくように、他の要素を押し下げるための`padding`が下部（水平スクロールの場合は右部）に追加されます。これがないと、固定された要素の下をスクロールしてしまうのです。
`false`を設定することで、ScrollTriggerにこのpaddingを追加しないようにすることができます。

`padding`の代わりに`margin`を使用したい場合は、`pinSpacing: "margin"`と記述します。

ただし、例えば、`display: flex`や`position: absolute`が設定されている親要素に固定した場合、余分な`padding`は他の要素を押し下げることができないので、手動でスペースを空けなければいけない場合があるかもしれません。

### pinType

**値形式：`fixed` | `transform`**

デフォルトでは、`position: fixed`はスクローラーが`body`である場合にのみピン留めに使用され、それ以外の場合は`transform`が使用されますが、`pinType: "fixed"`を設定することでScrollTriggerに`position: fixed`を使用させることができます。

通常、この設定は必要ありません。
ちなみに、CSSプロパティの`will-change: transform`を設定すると、ブラウザは`transform`が適用されたように扱い、`position: fixed`の要素を破壊してしまうので注意が必要です。（これはブラウザの仕様によるものです）

### preventOverlaps

**値形式：真偽値 | 文字列**

このプロパティは、ScrollTriggerがアニメーションを発火しようとするときに起動し、先行するScrollTriggerベースのアニメーションを探し、それらを強制的に終了させ、アニメーションが重複することを防ぎます。

任意の文字列を指定すると、一致する文字列を持つものだけにこの効果を適用させることができます。
例えば、`preventOverlaps: group1`と指定すると、`preventOverlaps: group1`を持つ他のScrollTriggerに適用させるということができます。

[デモ](https://codepen.io/GreenSock/pen/ZEyXPGj)

### refreshPriority

**値形式：数**
**デフォルト値：`0`**

ページ上で発生する順(上から下、左から右)にScrollTriggersを生成している限り、このプロパティを定義する必要はほとんどありません。また、このように順番に生成することが強く推奨されています。

しかし、そうでない場合は、`refreshPriority`を使用してScrollTriggersの更新優先度を設定します。
数字順に、0より1の方が後に更新されます。`z-index`と同じような使い方で、負の数を使用することもできますし、複数のScrollTriggerに同じ数を割り当てることもできます。

### scroller

**値形式：文字列 | 要素**

デフォルトでは、スクローラーはビューポートそのものですが、スクロール可能な`div`にScrollTriggerを追加したい場合は、それをスクローラーとして定義します。
セレクタには`#elementID`などのテキストを使用することもできますし、要素そのものを使用することもできます。

### scrub

**値形式：真偽値 | 数**

アニメーションの進行状況をスクロールバーに直接リンクします。
スムージングを適用して、アニメーションの進行状況をスクロールバーの位置に追いつくまでに少し時間がかかるようにすることもできます。

#### 真偽値指定の場合

`true`にすることで、アニメーションの進行状況をScrollTriggerの進行状況に直接リンクします。

#### 数値指定の場合

アニメーションの進行状況がスクロールバーの進行状況に追いつくまでのディレイ時間を設定できます。
つまり、`scrub: 0.5`とすると、アニメーションの進行状況がスクロールバーの進行状況に追いつくのに0.5秒かかります。

### snap

**値形式：数値| 配列 | 関数 | オブジェクト | `labels` | `labelsDirectional`**

スクロールを止めた後に、特定の進行値（0～1の間）にスナップすることができます。

#### 数値指定の場合

0〜1の間で指定します。
`snap: 0.1`であれば、0.1刻み（10％、20％、30％など）でスナップします。

セクションの数が決まっている場合は、単純に1 / (セクション数 - 1)で指定します。

#### 配列指定の場合

配列で指定した数値のうち、特定の進行値のいずれかにのみスナップさせることができます。
`directinal: false`を設定していない場合に有効です。

例えば、`snap: [0, 0.1, 0.5, 0.8, 1]`とすると、最後にスクロールした位置が配列中の一番近い値にスナップします。

#### 関数指定の場合

速度に基づいたスクロールの終了位置の値が入力され、返された値が最終的な進行値として使用されますので、好きなロジックを実行できます。
値は、常に0と1の間である必要があります。

例えば、`snap: (value) => Math.round(value / 0.2) * 0.2`とすると、0.2の増分が値として設定されます。

#### `"labels"`指定の場合

GSAPのタイムライン上で最も近いラベルにスナップします。
もちろん、タイムラインにはラベルが存在しなければいけません。

#### `"labelsDirectional"`指定の場合

タイムライン上で直近にスクロールした方向に存在する一番近いラベルにスナップします。

つまり、次のラベルに向かって少しだけスクロールして止めた時、現在のスクロール位置が前のラベルに最も近いとしても、スクローした先にある次のラベルにスナップします。こうすることによって、ユーザがより直感的に操作できるようになります。

#### オブジェクト指定の場合

以下のプロパティのいずれかでカスタマイズが可能です。（`snapTo`のみ必須プロパティ）

##### `snapTo`

**値形式：数 | 配列 | 関数 | `"labels"`**

前述の通り、スナップするロジックを指定します。

##### `delay`

**値形式：数**
**デフォルト値：スクラブ量の半分（スクラブが数字でない場合は0.1）**

最後のスクロールイベントからスナップアニメーションを開始するまでのディレイ（秒）を指定します。

##### `directional`

**値形式：真偽値**

デフォルトでは、スナップは方向性があり、ユーザーが最後にスクロールした方向に移動します。
`false`を設定することでこれを無効にすることができます。

##### `duration`

**値形式：数 | オブジェクト**

スナップアニメーションに要する時間（秒）を指定します。

`duration: 0.3`は常に0.3秒かかりますが、`duration: {min: 0.2, max: 3}`のようにオブジェクトとして範囲を定義することもできます。
オブジェクトとして範囲を定義することで、ベロシティに基づいて指定された範囲内にとどめさせることができます。
これにより、スナップポイントの近くでスクロールを停止した場合、自然に停止したポイントがスナップポイントから遠く離れている場合よりも、スナップにかかる時間が短くなります。

##### `ease`

**値形式：文字列 | 関数**
**デフォルト値：`power3`**

スナップするアニメーションにイージングを設定します。

##### `inertia`

**値形式：真偽値**
**デフォルト：`true`**

慣性の有無を指定します。
慣性をなくしたい場合に`false`に設定します。

##### `onStart`

**値形式：関数**

スナップが開始した時に呼び出される関数を指定します。

##### `onInterrupt`

**値形式：関数**

スナップが中断された時に呼び出される関数を指定します。

##### `onComplete `

**値形式：関数**

スナップが完了した時に呼び出される関数を指定します。

### start

**値形式：文字列 | 数 | 関数**
**デフォルト値：`top bottom`（pin: trueが設定されている場合は`top top`）**

ScrollTriggerの開始位置を指定します。
注意事項は`end`と同様です。

#### 文字列指定の場合

ScrollTriggerを起動するための、トリガーの位置とスクローラーの位置を記述します。

`top`、`bottom`、`center`（`horizontal: true`の場合は `left`、`right`）などのキーワードや、`80%`などのパーセント値、`100px`などのピクセル値を使用することができます。

キーワードを使用する場合、例えば、`top center`は、「トリガーの上部がスクローラーの中心に当たった時」という意味になります。
パーセント値やピクセル値を使用する場合、その値はトリガー要素やスクローラーのtop、leftからの相対値となります。

また、`top bottom-=100px`という相対値の記述もすることができ、「トリガーの上部がスクローラーの下部から100px上に当たった時」という意味になります。

#### 数指定の場合

スクロール値を指定します。

つまり、`200`とすれば、スクローラーがちょうど200pxスクロールしたとき発火します。

#### 関数指定の場合

動的に位置を計算する際に用いる関数を指定することができます。

この関数の返り値は、前述の通り文字列または数である必要があります。

### toggleActions

**値形式：文字列**
**デフォルト値：`play none none none`**

左から順番に*onEnter*、*onLeave*、*onEnterBack*、*onLeaveBack*の4つのトグル位置で、アニメーションをどのように制御するかを指定します。
使用できるキーワードは、再生：`play`、一時停止：`pause`、再開：`resume`、リセット：`reset`、初めから再生：`restart`、終了：`complete`、反転して再生：`reverse`、なし：`none`です。

例えば、`toggleActions: "play pause resume reset"`とすれば、トリガー要素に入ったときにアニメーションを再生（play）、トリガー要素から出た時に一時停止（pause）、後ろから戻ってきたときに再開（resume）、後ろからトリガー要素を出た時にリセット（reset）する、という意味になります。

### toggleClass

**値形式：文字列 | オブジェクト**

ScrollTriggerがactive/inactiveになったときに、要素にクラスを追加/削除します。

#### 文字列指定の場合

トリガー要素に追加するクラス名を指定します。
例：`toggleClass: "active"`

#### オブジェクト指定の場合

トリガー要素以外の要素のクラスをトグルするには、以下のようなオブジェクト構文で指定します。
`{targets: ".my-selector", className: "active"}`

`targets`には、セレクタのテキスト、要素の直接参照、または要素の配列を指定できます。

### trigger

**値形式：文字列 | 要素**

ScrollTriggerの開始位置を計算するためのトリガー要素を指定します。

## 終わりに

以上、プロパティ一覧となります。

理解を深めるための手っ取り早い方法が、動いているものを見ることだと思います。
ScrollTriggerのDemoが[公式ページ](https://greensock.com/docs/v3/Plugins/ScrollTrigger)にありますので、これを覗きながらどんなプロパティを用いているのか参考にしてみてください。