Three.js で遊び倒す -カメラを動かそう Part.3 -

Three.js day 6 となりました。

本日も、カメラを動かしていきます。
インタラクションを取り入れます。

#1. 完成版
<p class="codepen" data-height="539" data-theme-id="0" data-default-tab="html,result" data-user="hiroyaiizuka" data-slug-hash="KEYqRQ" style="height: 539px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="mouseMoveX, Z(experimental)">
  <span>See the Pen <a href="https://codepen.io/hiroyaiizuka/pen/KEYqRQ/">
  mouseMoveX, Z(experimental)</a> by hiroya iizuka (<a href="https://codepen.io/hiroyaiizuka">@hiroyaiizuka</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#2. 参考文献
[マウスイベントで取得されるカーソル座標パラメータの整理(offset, page, screen, client)](https://qiita.com/yukiB/items/31a9e9e600dfb1f34f76)
[ICS MEDIA](https://ics.media/tutorial-three/index.html)
[初めてのThree.js](https://www.amazon.co.jp/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AEThree-js-%E7%AC%AC2%E7%89%88-%E2%80%95WebGL%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEJavaScript-3D%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA-Dirksen/dp/4873117704)



#3. 分解してみる


❶. 
[前回](https://qiita.com/duka/items/b6989d24b60cf3dbde48)、camera.lookAt() を使い、中央を注視しながら、カメラを動かしました。


今回は、マウスを動かしたら、画面も動くようにましょう。

##1. マウス座標の取得
マウスを動かすには、どうしたらよいでしょうか？
まず、マウス座標を取得する必要がありますね。

マウス座標のパラメーターには、``pageX``, ``clientX``, ``offset`` などがあります。

###clientX
``ブラウザウィンドウ``のなかで、マウス座標を取得するパラメーターです。
ウィンドウの左上が、(0 , 0) になります。
``event.clientX`` で、X 座標が取得できます。


###pageX
``ページ全体``での、マウス座標を取得するパラメーターです。
clientX との違いは、スクロールすることで明瞭になります。
pageX は、page全体から座標を作るため、スクロールして下に移動した時に注意が必要です。
つまり、見えていない領域を計算に入れて、座標を作らなければいけません。

今見えているウィンドウのみから計算する、clientX とは誤差が生まれるわけですね。
今回は、スクロールしないのでどちらでも良いですが、clientX を使います。

両者の違いについて、詳細は、[こちら](https://qiita.com/yukiB/items/31a9e9e600dfb1f34f76) の記事を参照ください。

##2. mousemove イベントを設定しよう

[色々な方法](https://www.w3schools.com/jsref/event_onmousemove.asp) がありますが、addEventListener を使いましょう。

```
let mouseX = 0;
document.addEventListener("mousemove", (e)=>{
  mouseX = e.clientX
})
```
このmouseX をcamera.position.x に組み込めば、完成です。

```index.html
    let rot = 0;
    let mouseX = 0;

    document.addEventListener("mousemove", event => {
          mouseX = event.clientX;
    });

    function renderScene() {
         
          camera.position.x += (mouseX - camera.position.x) * 0.005;
          camera.lookAt(new THREE.Vector3(0, 0, 0));

          requestAnimationFrame(renderScene);
          renderer.render(scene, camera);
    }
```

<p class="codepen" data-height="226" data-theme-id="0" data-default-tab="html,result" data-user="hiroyaiizuka" data-slug-hash="OqGgRN" style="height: 226px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="mouseMoveX (experimental)">
  <span>See the Pen <a href="https://codepen.io/hiroyaiizuka/pen/OqGgRN/">
  mouseMoveX (experimental)</a> by hiroya iizuka (<a href="https://codepen.io/hiroyaiizuka">@hiroyaiizuka</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


mouse の動きに対応して、画面が動くようになりました。
しかし、表現としては、まだいまいちですね・・・。
<br/>
z座標にも、このmousemove action を取り入れましょう。

```index.html
 function init() {
        let rot = 0;
        let mouseX = 0;
        let mouseY = 0;

        document.addEventListener("mousemove", event => {
          mouseX = event.clientX - 2 * window.innerWidth;
          mouseY = event.clientY;
        });

 function renderScene() {
        camera.position.x += (mouseX - camera.position.x) * 0.05;
        camera.position.z += (mouseY - camera.position.z) * 0.05;
        camera.lookAt(new THREE.Vector3(0, 0, 0));

        requestAnimationFrame(renderScene);
        renderer.render(scene, camera);
    }
 }
```

<p class="codepen" data-height="428" data-theme-id="0" data-default-tab="html,result" data-user="hiroyaiizuka" data-slug-hash="KEYqRQ" style="height: 428px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="mouseMoveX, Z(experimental)">
  <span>See the Pen <a href="https://codepen.io/hiroyaiizuka/pen/KEYqRQ/">
  mouseMoveX, Z(experimental)</a> by hiroya iizuka (<a href="https://codepen.io/hiroyaiizuka">@hiroyaiizuka</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

さっきより、豊かな動きになりました！

余談ですが、以下のコード

```
camera.position.x += (mouseX - camera.position.x) * 0.05;
```

は、イージングの公式と言われるものです。
``現在の値 += (目標値 - 現在の値) * イージング係数``

で設定できます。
CSS animation でも、ease-in ease-out などありましたね。
この公式を使うことで、動きがより滑らかになるので、適宜取り入れていきましょう。

それでは、また明日〜