Computer >> 컴퓨터 >  >> 프로그래밍 >> HTML

HTML5 캔버스에서 다중 클릭 이벤트를 사용하는 방법

HTML5 캔버스에서 다중 클릭 이벤트를 사용하는 방법

캔버스에 하나의 원이 그려져 있고, 그 원의 절반은 빨간색, 일부는 회색으로 칠해져 있다고 가정해 보겠습니다. 이 상태에서 빨간색 영역을 클릭하면 function1을, 회색 영역을 클릭하면 function2를 호출해야 하는 상황입니다.

이처럼 하나의 캔버스에서 영역별로 서로 다른 클릭 이벤트를 처리하려면, 클릭 여부를 검사할 각 영역을 미리 저장해 두는 재사용 가능한 경로(Path) 객체가 필요합니다. 클릭 핸들러(click handler)를 사용하면 하나의 캔버스를 공유하면서 원하는 작업을 수행할 수 있으며, Path2D 객체를 활용하면 각 영역의 경로 정보를 체계적으로 관리할 수 있습니다.

1단계: Path2D 객체로 클릭 영역 정의하기

먼저 Path2D 객체를 생성하고, 각각 빨간색 영역과 회색 영역에 해당하는 호(arc) 경로를 정의합니다. 생성된 경로들을 배열에 담아두면 나중에 반복문으로 한 번에 검사할 수 있습니다.

var path1 = new Path2D();
var path2 = new Path2D();

// 클릭 검사를 위해 경로들을 배열에 저장
var newpaths = [path1, path2];

// 빨간색 영역에 해당하는 경로
path1.arc(200, 85, 60, -0.2 * Math.PI, 2.7 * Math.PI);

// 회색 영역에 해당하는 경로
path2.arc(200, 85, 60, 2.7 * Math.PI, -1.1 * Math.PI);

// 두 개의 경로 객체를 동일한 컨텍스트(ctx1)로 렌더링하되, 스타일만 다르게 지정
ctx1.lineWidth = 16;
ctx1.strokeStyle = "#d43030";
ctx1.stroke(path1);
ctx1.strokeStyle = "#b8b8b8";
ctx1.stroke(path2);

2단계: 캔버스에 클릭 핸들러 등록하기

다음으로 캔버스에 클릭 이벤트 리스너를 등록합니다. 클릭이 발생하면 마우스 포인터의 x, y 좌표를 구한 뒤, 앞서 만든 경로 배열을 순회하면서 각 경로와 클릭 지점이 겹치는지 확인하는 히트 테스트(hit test)를 수행합니다.

var canvas = document.getElementById("myCanvas1");
var ctx = canvas.getContext("2d");

canvas.addEventListener("click", function (e) {
  // 캔버스 내부의 실제 좌표 계산
  var rect = canvas.getBoundingClientRect();
  var x = e.clientX - rect.left;
  var y = e.clientY - rect.top;

  // 경로 배열을 순회하며 클릭된 영역 검사
  newpaths.forEach(function (path, index) {
    if (ctx.isPointInPath(path, x, y)) {
      if (index === 0) {
        function1(); // 빨간색 영역 클릭 시 실행
      } else {
        function2(); // 회색 영역 클릭 시 실행
      }
    }
  });
});

3단계: HTML 캔버스 요소 준비하기

마지막으로 자바스크립트 코드가 참조할 캔버스 요소를 HTML에 추가하고 연결합니다.

<canvas id="myCanvas1"></canvas>

핵심 포인트 정리

  • Path2D 객체: 클릭 판정이 필요한 각 영역을 독립적인 경로로 저장하여 재사용할 수 있습니다.
  • isPointInPath(): 특정 좌표가 경로 내부에 포함되어 있는지 확인하는 히트 테스트 메서드입니다.
  • 배열 순회: 여러 경로를 배열에 담아 반복문으로 검사하면, 영역이 늘어나도 코드를 쉽게 확장할 수 있습니다.
  • 좌표 보정: getBoundingClientRect()를 사용해 화면 좌표를 캔버스 내부 좌표로 변환해야 정확한 판정이 가능합니다.

이렇게 하면 하나의 캔버스 안에서 색상 영역별로 서로 다른 함수를 호출하는 다중 클릭 이벤트를 깔끔하게 구현할 수 있습니다.