前回の第9回「マウスイベントを扱う」では、3次元空間に置いた立方体のオブジェクトにマウスのロールオーバー/ロールアウト、クリックへのインタラクションを加えた。今回は、これらのオブジェクトを回り込んで捉えるカメラの位置も、マウスポインタの動きに応じて変えてみたい。
マウスポインタの水平の位置に応じてカメラを回り込ませる
まず、オブジェクトの周囲を回るカメラの水平の動きだ。画面の中心から見たマウスポインタの水平位置に応じて、回り込む向きと速さを変えてみよう。第9回コード2「ロールオーバーしたオブジェクトの大きさが変わる」につぎのような手を加える。
画面の中心座標は変数(centerXとcenterY)に納めておく(垂直座標も後ほど使うので変数を設けておいた)。そして、マウスポインタが動いたときのonmousemoveイベントハンドラを定めた。コールバック関数(recordMouse())は、イベントオブジェクト(eventObject)のMouseEvent.clientXプロパティから得たマウスポインタの水平座標を変数(lastX)に記録している。カメラを回り込ませる関数(rotate())は、マウスポインタと画面の中心の水平座標の差に応じて回す角度(angle)を変えることにした。
これで、マウスポインタの水平位置に応じて、回り込むカメラの向きと速さが変わる。しかし、これだけでは、カメラの動きが少し気になる。onmousemoveハンドラは、Away3DのViewオブジェクトに定めた領域の外でもイベントを拾う。そして、ポインタの位置を遠ざけるほど、カメラがぐるぐると速く回ってしまう(図1)。
Viewオブジェクトの領域を超えても、カメラの速さはそれ以上増さないようにしたい。そこで、つぎのようにコールバック関数(recordMouse())で、マウスポインタの水平座標がViewオブジェクトに定めた幅(stageWidth)を超えたら、座標値はその幅止まりとして扱うようにした。
これで、3次元領域の中心からのマウスポインタの水平位置に応じて、立方体のオブジェクトを捉えるカメラの回り込む向きと速さが変わるようになった。第9回コード2を手直ししたのが、つぎのコード1だ。
マウスポインタの垂直の位置に応じてカメラを上下する
つぎに、カメラに上下の動きも加えたい。やはり、画面の中心から見たマウスポインタの垂直位置に応じて動かす。onmousemoveイベントハンドラのコールバック関数(recordMouse())で、つぎのようにイベントオブジェクト(eventObject)のMouseEvent.clientYプロパティから得たマウスポインタの垂直座標を変数(lastY)に記録した。なお、3次元の表示領域の高さ(stageHeight)を超えたら、座標値は増やさないことにしている。ここまでは、カメラを水平に回すのと同じ考え方だ。
カメラの垂直の動きは、水平と同じようにぐるぐる回しては、天地がひっくり返ってしまう。したがって、カメラを動かす関数(setCamera())では、係数(-10)で幅をもたせて垂直座標を上下するようにした。これで、マウスポインタの水平の動きによる回転だけでなく、垂直座標に応じてカメラが上下するようになる(図2)。さて、このたびのお題はでき上がりだ。スクリプトは以下のコード2にまとめた。併せて、サンプル1をjsdo.itに掲げてある。
減速を表す式 ー イーズアウト
結びとして、オブジェクトを動かす式について、少し補っておこう。カメラを水平および垂直に動かすとき、その度合いはつぎのような式で定めた。すると、マウスポインタの動きがそのままカメラに伝わるのではなく、加速や減速が与えられる。
この式は、一般につぎのように表される。アニメーションは、目標の位置に近づくほど動きが遅くなる(図3)。目標値と現在値の差に速度を比例させているからだ。終わりに近づくにつれ減速する動きは「イーズアウト」と呼ばれる。インターフェイスなどでおなじみだろう。比例係数(減速率)には、0から1の間の数値を与える。
位置を速度に足し込んでつぎの位置を求めるというのは、数学の微分の考え方にもとづく。つまり、広く一般に使える。ただ、「微分」と聞くと身構えてしまう人が多い。けれど、「考え方」としては、位置の時間にもとづく変化が「速度」で、それを時々刻々「位置」に加えれば物体の運動が表せるということにすぎない。
この「考え方」を用いると、一見複雑そうな動きが簡単な四則演算で表せることも少なくない。「イーズアウト」はそのひとつの例だ。また、連載「HTML5のCanvasでつくるダイナミックな表現―CreateJSを使う」で解説したつぎのサンプル2は、バネのように弾みのついた動きを四則演算で導いている(「マウスポインタの軌跡を滑らかな線で描きながら消す」参照)。
微分計算そのものはしなくても、その考え方を知るだけで、運動の式の扱いについて応用の幅が広がる。たとえば、Webに公開されたサンプルコードを開いて見たときも、読み解く力が備わるだろう。興味をもたれた読者は「速度から位置を決めるアニメーション ー 微分により運動を考える」をお読みいただきたい(15分間の講演録画も掲載)。