[react] 클릭 위치에 점 찍기 (히트맵)

강인호·2023년 2월 9일
0

개인저장

목록 보기
77/87

특정 위치를 클릭하면 점이 찍히고 위치정보를 저장해야 하는 기능을 만들어야 하는 일이 생겼다.

더 정확히는 클릭하면 위 사진처럼 빨간점이 찍히고 빨간점이 네모로부터 얼마나 떨어져있는지에 대한 값을 구해야했다.

위 처럼 클릭 이벤트의 절대좌표에서 네모 엘리먼트의 절대좌표를 뺀다면 클릭한 위치가 엘리먼트로부터 얼마나 떨어져 있는지를 알 수 있다.

  const RecordClick = e => {
  // 여기서의 이벤트는 클릭 이벤트 객체 
  (이벤트 리스너의 콜백함수로 들어갈 함수)
      
    const sidePosition = {
      X: Math.floor(e.target.getBoundingClientRect().left + window.pageXOffset),
      Y: Math.floor(e.target.getBoundingClientRect().top + window.pageYOffset),
    };
    
    // 클릭한 엘리먼트의 절대좌표
    // .getBoundingClientRect().left 뷰포트 기준 X값 top은 Y 값 
    // pageOffset은 오프셋으로부터 계산한 스크롤 가로길이
    
        const clickPosition = {
      X: Math.floor(e.clientX) + window.pageXOffset,
      Y: Math.floor(e.clientY) + window.pageYOffset,
    };
    // 클릭 이벤트의 좌표 어차피 서로 뺄거라 기준만 맞추면 됨
    }

콘솔을 찍어보면 페이지 기준 엘리먼트 값의 좌표와

페이지 기준 클릭 이벤트의 좌표가 나온다. 클릭값에서 엘리먼트 값을 빼주면 엘리먼트 기준 상대좌표를 구할 수 있다.

상대 좌표를 구한다면 그 위의 점을 찍을수가 있는데

상대좌표 자체가 '기준점으로부터 좌측으로 얼마 상단으로부터 얼마 떨어져 있는지를 픽셀단위로 구한 값'

이므로 기준점을 relative로 한 absolute의 top과 left값으로 넣기만 하면 해당 클릭점에 점을 찍을 수 있다.

하지만 나는 세부 픽셀이 달라도 동일한 위치에 점이 찍히게 하고 싶어서 해당 상대좌표의 값이 전체 엘리먼트의 몇 퍼센트인지를 계산하고 top left값에 역산하여 넣기로 했다.

 const ratio = {
      X: clickPosition.X - sidePosition.X,
      Y: clickPosition.Y - sidePosition.Y,
    };
    
    // 상대 좌표
    
    const XPer = (ratio.X / Number(pullWidth)) * 100;
    const YPer = (ratio.Y / Number(pullHeight)) * 100;
    const xyPer = { XPer: XPer.toFixed(2), YPer: YPer.toFixed(2) };
    
        setClickArr([...clickArr, xyPer]);
        
        // 스테이트 배열에 넣어준다
    // 백분율


다음과 같은 형식으로 map을 돌렸다. 720 1920 자리에는 props로 높이와 길이를 받아와서 컴포넌트 형식으로 사용하게 리팩토링할 예정.

크기가 달라도 상대적인 퍼센트로 계산하여 점을 찍기 때문에 균일한 위치에 점이 찍힌다.

//

낯선 개념이였지만 처음에 의도한 결과물이 나와서 만족스러웠고 재밌었다.

그리고 일에 열중하느라 저번달 회고를 못써버렸다..

0개의 댓글