今更だからこそ、ちゃんとやる横スクロール（ScrollTrigger）

# はじめに
皆さん、サイトに横スクロールを実装されたことはありますしょうか？
ScrollTriggerで横スクロールが簡単に作れてしまうことはご存知の方も多いと思います。

しかし、簡単に実装できてしまうが故に気をつけなければならないこと、やってみるとうまくいかないことが出てくると思います。

そのあたりを今回拾って行ましょう。

# まずはシンプルに横スクロール

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="dyjbrNP" data-user="watanabe-hazime" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/watanabe-hazime/pen/dyjbrNP">
  horizontal scroll sample01</a> by watanabe (<a href="https://codepen.io/watanabe-hazime">@watanabe-hazime</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

単純に横スクロールを実装するだけならこれで完成になります。
使っているScrollTriggerの詳細や解説は、こちらの記事でわかりやすく説明されております。

https://liginc.co.jp/548232

ただ、これだけでは公開レベルに至りません。

# アップデートポイント
1. 高さに対する注意
2. scrubの値
3. endの値によるスクロールの重さ
4. 横スクロール中のアニメーションの発火タイミング

## 1. 高さに対する注意
実は上のcodepenで既に実装してしまっているのですが、
横スクロールを実装する場合、横スクロールのセクションを画面の高さ100%にすることが多いと思います。
ただ、画面の高さ100%にするが故に中のテキストや画像などのコンテンツの高さも合わせて可変にしておかないと表示が崩れてしまいます。

```scss: 高さを可変に
@function vh($size) {
  @return (100/700) * $size * 1vh;
}
```
SCSSのfunctionを使って画面の高さで可変するようにします。

また、このままだと画面の高さによってどこまでも大きくなってしまうので、最大サイズを決めましょう。
```scss: 高さを可変に
.text {
  font-size: vh(16);
  @media screen and (min-height: 700px) {
    font-size: 16px;
  }
}
```
今回は高さ700pxまでを可変サイズにして、それ以上の場合は固定サイズにしています。
固定サイズにする場合は上のcodepenでもやっているようにコンテナ要素に **align-items: center** を設定し、
横スクロール内の各セクション（もしくは各セクションのインナー）に **max-height** を設定するなどして画面中央にコンテンツが来るように調整しましょう。 

## 2. scrubの値
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="JjBPzgX" data-user="watanabe-hazime" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/watanabe-hazime/pen/JjBPzgX">
  horizontal scroll sample01.2</a> by watanabe (<a href="https://codepen.io/watanabe-hazime">@watanabe-hazime</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

特に出る時がわかりやすいのですが、横スクロールエリアの最後までスクロールする前に縦スクロールに戻ってしまいます（斜めに移動する感じ）。

なので、scrubの値は**0**または**true**にするのがいいでしょう。

## 3. endの値によるスクロールの重さ
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="eYjOXaw" data-user="watanabe-hazime" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/watanabe-hazime/pen/eYjOXaw">
  horizontal scroll sample01.1</a> by watanabe (<a href="https://codepen.io/watanabe-hazime">@watanabe-hazime</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

```javascript: endの値によってスクロールの重さが変わります
end: () => return '+=' + (container.clientWidth - wrapper.clientWidth + 3000)
```
今回はデフォルト値に3000を追加しています。
codepenを触ってもらえればわかるかと思いますがendの値によって横スクロールをしている時のスクロールの重さが変わってきます。
もし「横スクロールエリアをじっくり見せたい」と言ったことがあれば、わざと重くしてみるのもありかもしれません。

## 4. 横スクロール中のアニメーションの発火タイミング
横スクロールの中でスクロールに合わせてアニメーションを発火させたい場合、特別な方法が必要になります。
水平方向のスクロールはGSAPによって実装されたアニメーションであり、ネイティブのスクロールではないため普通の作法ではScrollTriggerが発火してくれません。

### containerAnimation
プロパティについてはこちらの記事で解説されています。

https://qiita.com/heeroo_ymsw/items/ae22e4cee8c6a08ff852#containeranimation

また、containerAnimationが実装されたGSAPのアップデート情報はこちらです。

https://greensock.com/3-8/

containerAnimationを反映したcodepenはこちら
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="abjoMab" data-user="watanabe-hazime" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/watanabe-hazime/pen/abjoMab">
  horizontal scroll sample02</a> by watanabe (<a href="https://codepen.io/watanabe-hazime">@watanabe-hazime</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### .isInViewport
```javascript: 要素がビューポート内にある場合、true を返す。
if (ScrollTrigger.isInViewport(element, 0.2, true)) {

}
```
引数には以下を渡すことで、設定に合わせて要素がビューポートに入った時に **true** を返してくれます。
・第一引数：監視する要素
・第二引数：要素がビューポート内にどれだけの割合入った時にtrueを返すか（数値）
・第三引数：デフォルトでは垂直方向、trueにすると水平方向を監視する

また、.isInViewport()はただ設置しただけ動いてくれませんので、**onUpdate** などに入れる必要があります。

.isInViewport()を反映したcodepenはこちら（セクション01は垂直方向監視で設置）
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="yLqBwxG" data-user="watanabe-hazime" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/watanabe-hazime/pen/yLqBwxG">
  horizontal scroll sample03</a> by watanabe (<a href="https://codepen.io/watanabe-hazime">@watanabe-hazime</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# まとめ
ここまで横スクロールの改善方法を紹介してきました。

正直、横スクロールを実装したサイトを制作するのであれば、この辺りのポイントは当たり前にできていないといけないポイントかと思います。
その上でもっと良くしていくために、横スクロールエリアに入る時や出る時にシームレスになるように演出を入れたり、スムーズスクロールを入れたりなどの工夫がすることで、良い横スクロールサイトができるのではないかと思っております。

以上、読んでいただきありがとうございました。