3Dパララックスエフェクトを簡単にキメる３つの法則

# 誰に向けた内容か
- JavaScript を用いてクリエイティブコーディングができる人、興味がある人
- JavaScript ライブラリ「GSAP」を用いてアニメーション実装できる人、興味がある人
- パララックスエフェクトを実装できる人、興味がある人

# この記事で解説すること

3D パララックスエフェクトを簡単に実装する TIPS を紹介します。

以下の CodePen 作品は 3D パララックスエフェクトの使用例です。
Result エリアをスクロールして、アニメーションを確かめてください。
この記事を読むと、3D パララックスエフェクト作成方法のエッセンスを学べます。

### 3D パララックスエフェクトの使用例
<p class="codepen" data-height="300" data-default-tab="js,result" data-slug-hash="XWOOamr" data-user="YusukeNakaya" 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/YusukeNakaya/pen/XWOOamr">
  GSAP: ScrollTrigger Sample4</a> by Yusuke Nakaya (<a href="https://codepen.io/YusukeNakaya">@YusukeNakaya</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# サンプル完成品

以下リンクは、本記事で使うサンプルの完成品です。
[サンプル作品（CodePen）](https://codepen.io/YusukeNakaya/pen/QWYXqqZ)

# ３つの法則
1. **レイヤー** を作ってオブジェクトを配置する
1. スクロールに連動して **レイヤーの scale を変更** する
1. あえて **動かないものを配置** する

この３つを意識すれば、比較的簡単に実装できます。
それぞれ解説します。

# 法則1: レイヤーを作ってオブジェクトを配置する

オブジェクト1つに対し、1つのレイヤーを作ります。
レイヤーは１つずつ画面全体に広げます。
レイヤーの中にオブジェクトを１つ配置します。
背景もテキストも、表示するものすべてをオブジェクトとして考えます。


```HTML
<div class="layer -bg">
  <div class="bg"><!-- 背景 --></div>
</div>

<div class="layer -text">
  <d class="text">
    <h1>Hello CodePen!<br>I'm Yusuke.<br>I love WebDev!</h1>
  </div>
</div>

<div class="layer -deco1">
  <div class="deco1"><!-- 装飾 --></div>
</div>
```

```CSS
.layer {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
```

# 法則2: スクロールに連動してレイヤーの scale を変更する

レイヤーを拡大します。
オブジェクトを直接拡大しません。
理由は、画面の中央に拡大縮小の中心点を設定したいからです。

それぞれのオブジェクトに `transform-origin` を指定すれば可能ですが、
オブジェクトの位置を変更するとき、コード変更の手間がより多くかかります。

```JavaScript
let scale = {
  bg: 1,
  text: 1,
}

window.addEventListener('wheel', event => {
  scale.bg += event.deltaY / 80000
  scale.text += event.deltaY / 4000
  
  gsap.to('.layer.-bg', {
    scale: scale.bg,
  })

  gsap.to('.layer.-text', {
    scale: scale.text,
  })
})
```

# 法則3: あえて動かないものを配置する

オブジェクトがにぎやかに動く中、動かないものを配置すると、
より視差を感じさせる効果があります。

このような3Dでは、オブジェクトがはみ出るようにフレームを配置すると、
より奥行きのある立体感を演出できます。

```HTML
<div class="layer -frame">
  <div class="frame"><!-- フレーム --></div>
</div>
```

```CSS
.frame {
  position: absolute;
  top: 20px;
  left: 20px;
  width: calc(100% - 40px);
  height: calc(100% - 40px);
  border: 3px solid #fff;
  box-sizing: border-box;
}
```

以下のサンプルでは、窓の奥から手前に向けて、鳥が飛んでくるように見えませんか？
実際にそのような実装はなく、錯覚として「そう見える」だけです。


### フレームを用いた錯覚の使用例
<p class="codepen" data-height="507.5546875" data-default-tab="result" data-slug-hash="wvvzQmO" data-user="YusukeNakaya" style="height: 507.5546875px; 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/YusukeNakaya/pen/wvvzQmO">
  Only CSS: Sunset Bird Reverse</a> by Yusuke Nakaya (<a href="https://codepen.io/YusukeNakaya">@YusukeNakaya</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# 終わりに

本記事があなたのテクニック向上に寄与できれば嬉しいです。

CodePen でたくさんの作品を投稿しています。よかったらご覧ください！
[CodePen](https://codepen.io/YusukeNakaya)

主に X(Twitter) を使っています。よかったらフォローしてください！
[Yusuke Nakaya](https://twitter.com/s14garnet)