LoginSignup
0
0

More than 3 years have passed since last update.

フロントエンド開発者のための刺激的なプロジェクト10選 1選目考察【後編】

Last updated at Posted at 2021-03-28

前編に続き、

を、考察していきます。プロジェクト1選目は、下記リンクにて確認できます。

getBoundingClientRect()

任意の要素の大きさ(height,width)と、ビューポートに対する位置を返す。

clientX clientY

イベント発生時のマウスの座標を返す。
このプロジェクトではmousemoveイベントが発生した時にカーソルの位置を取得しています。

// Mouse position
const useMousePosition = () => {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  useEffect(() => {
    const setFromEvent = e => setPosition({ x: e.clientX, y: e.clientY });
    window.addEventListener("mousemove", setFromEvent);

    return () => {
      window.removeEventListener("mousemove", setFromEvent);
    };
  }, []);

  return position;
};

Math.atan2(y,x)

指定した座標を元に平面上の角度を取得できる。第1引数にy座標、第2引数にx座標を指定するのに注意。このプロジェクトでは上記のgetBoundingClientRectclientX clientYで取得した座標を元に、画面右下のマウスをキャッチしてくるおじさんから角度を計算しています。


const Grabber = ({ state, gameOver, extended, onCursorGrabbed }) => {
  const mousePos = useMousePosition();
  const [ref, position] = usePosition();
  const hasCursor = false;

  // Calculate rotation of armWrapper
  const x = position.left + position.width * 0.5;

  const y = position.top + position.height * 0.5; 

  const angle = gameOver ? 0 : Math.atan2(mousePos.x - x,-(mousePos.y - y)) * (180 / Math.PI);

  // Ensure value is within acceptable range (-75 to 75)
  const rotation = Math.min(Math.max(parseInt(angle), -79), 79);

  const grabberClass = `grabber grabber--${state} ${extended && "grabber--extended"}`;
  const wrapperStyle = { transform: `rotate(${rotation}deg)` };

  let handImageSrc = ASSETS[state];

  return (

    <div className={grabberClass}>
      <div className="grabber__body"></div>
      <img className="grabber__face" src={ASSETS.head} />
      <div className="grabber__arm-wrapper" ref={ref} style={wrapperStyle}>
        <div className="grabber__arm">
          <img
            className="grabber__hand"
            src={handImageSrc}
            onMouseEnter={onCursorGrabbed}
          />
        </div>
      </div>
    </div>
  );
};

Math.atan2で計算した角度はラジアンなので、度数法に変換するために、(180 / Math.PI)を乗じています。
ここまでは理解できたのですが、本来ならy座標を指定する第1引数にx座標、x座標を指定する第2引数にy座標を指定している点や、変数rotationの計算式で出てくる79-79いう数字の意味が理解できませんでした。
どなたか解説頂けると幸いです。

アウトプット

この前編、後編の考察で学んだことをアウトプットしてみました。
下のリンクをクリックすると柴犬をなでなでできると思うので、なでていってやってください。(スマホ対応してないです。)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0