Mouse Stalker

by yshrkn

HTML

<div id="canvas">
  <div class="ball" id="ball"></div>
  <div class="ball ball--small ball--red" id="small-ball"></div>
</div>

CSS

html,
body {
  height: 100%;
}

body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  padding: 20px;
}

.ball {
  border-radius: 50% 50%;
  background-color: black;
  width: 100px;
  height: 100px;
  transform: translate(-50%, -50%);
  position: absolute;
  top: 50%;
  left: 50%;
  cursor: pointer;
}

.ball--red {
  background-color: #c00;
}

.ball--small {
  width: 50px;
  height: 50px;
}

JavaScript

/**
 * 以下の要件を満たす、マウスストーカー表現を作成してください。
 *
 * - ビューの更新には、requestAnimationFrameを使ってください。
 * - 赤と黒のballそれぞれで、追従速度が異なるようにしてください。
 * - マウスを追従しているballをクリックすると、マウスへの追従を停止します。
 * - 追従停止しているballをクリックすると、再びマウスへの追従を開始します。
 */
 
 /*
 Point

教材では説明がありませんが、重要な機能です!
アニメーションなど、画面のレンダリング処理の更新を滑らかに行いたい(コマ落ちを抑制したい)場合は、setInterval や setTimeout ではなく、requestAnimationFrame を利用します。
Hint

ロジック

以下の処理を、requestAnimationFrame により実行します。

マウスカーソルとball間の「x座標間の距離/y座標間の距離」をそれぞれ算出します。
ここでは便宜的に「距離」といいましたが、正確には「ベクター(距離と方向を持ちます)」です。
(距離は常に「正」の値ですが、ベクターは「負」の値を持つこともあります)

上記値に 減速率を乗算します。
最初は0.1 などを設定し、値を調整してみると良いでしょう。
この値が小さければ小さいほど、ballはゆっくりとマウスに近づきます。

上記値を現在のballのx座標とy座標に加算します。

日本語で考える

プログラミングを行う前に、まずはロジックを 「日本語で考えてみましょう」
上記説明のロジックに従うと、画面のリフレッシュ(アニメのループ処理)で、ballの座標は更新の度に、どのように定義されるでしょうか?ロジックが理解できれば、あとは実装あるのみです!!
More

今回は、ball を絶対配置し、top、left プロパティを操作していますが、これを translateで置き換えることにより、GPUの高速化の恩恵を受けることができます。
 */