문제

HTML Canvas Element에 커서 위치와 실제 그림이 그려지는 위치가 다름

원인

  1. 캔버스 크기(styled-components)와 실제 캔버스 사용처(return 부분)에 각자 다르게 설정돼 있었음. 또한 vw, vh로 캔버스 크기를 설정해줄 경우, resizing을 해주는 함수를 따로 만들어서 useEffect에 eventListener로 설정해줘야함
  2. 위의 원인을 제거해도 커서위치가 맞지 않음, 따라서 그려지는 위치의 좌표를 잡는 함수를 다시한 번 살펴보게 됨.

해결

원래 코드

const getCoordinates = (
    event: React.MouseEvent<HTMLCanvasElement>
  ): Coordinate | undefined => {
    if (!canvasRef.current) {
      return;
    }
    const canvas: HTMLCanvasElement = canvasRef.current;
    return {
      x: event.pageX - canvas.offsetLeft,
      y: event.pageY - canvas.offsetTop,
    };
  };

**pageX**와 **pageY**는 문서 전체에서의 마우스 좌표를 나타내는 반면, **clientX**와 **clientY**는 뷰포트(viewport) 내에서의 마우스 좌표를 나타냄. 따라서 **clientX**와 **clientY**를 사용하여 뷰포트 내에서의 마우스 좌표를 구해야 하는 것이었음.

변경된 코드

const getCoordinates = (
    event: React.MouseEvent<HTMLCanvasElement>
  ): Coordinate | undefined => {
    if (!canvasRef.current) {
      return;
    }
    const canvas: HTMLCanvasElement = canvasRef.current;
    const rect = canvas.getBoundingClientRect(); // 캔버스의 뷰포트 상의 위치 정보를 가져옴
    return {
      x: event.clientX - rect.left,
      y: event.clientY - rect.top,
    };
  };

캔버스의 뷰포트 상의 위치 정보를 가져오고, 이벤트의 기준을 pageX, pageY가 아닌 clientX, clientY로 변경해줌.

⇒ 커서와 위치가 잘 맞는다.