캔버스(<canvas>) 요소 안에 그려진 도형들은 DOM에 별도의 표현(representation)을 갖지 않습니다. 캔버스에는 픽셀과 색상 정보만 존재할 뿐이며, 그리기 작업은 즉시 모드(immediate mode)로 비트맵을 그리는 방식으로 처리됩니다.
따라서 캔버스 위의 특정 도형에서 클릭 이벤트를 감지하려면, 캔버스 HTML 요소 자체에서 클릭 이벤트를 받은 뒤 마우스 좌표를 계산하여 어떤 도형이 클릭되었는지 직접 판별해야 합니다. 이를 위해서는 각 도형의 위치(left, top)와 크기(width, height) 정보를 미리 저장해 두어야 합니다.
캔버스에 클릭 이벤트 리스너 추가하기
캔버스 요소에 클릭 이벤트를 등록하는 기본 코드는 다음과 같습니다.
canvas.addEventListener('click', function() { }, false);예제: 클릭된 도형 판별하기
어떤 도형이 클릭되었는지 확인하려면, 클릭 지점의 좌표를 구한 후 각 도형의 영역과 비교하면 됩니다. 아래 코드를 참고하세요.
var e = document.getElementById('myCanvas'),
elemLeft = e.offsetLeft,
elemTop = e.offsetTop,
context = e.getContext('2d'),
elements = [];
// 클릭 이벤트 리스너 등록
e.addEventListener('click', function(event) {
var xVal = event.pageX - elemLeft,
yVal = event.pageY - elemTop;
console.log(xVal, yVal);
elements.forEach(function(ele) {
if (yVal > ele.top && yVal < ele.top + ele.height &&
xVal > ele.left && xVal < ele.left + ele.width) {
alert('element clicked');
}
});
}, false);
// 클릭 판정 대상이 되는 도형 정보 저장
elements.push({
colour: '#1C2128',
width: 250,
height: 200,
top: 30,
left: 20
});
// 저장된 도형을 캔버스에 그리기
elements.forEach(function(ele) {
context.fillStyle = ele.colour;
context.fillRect(ele.left, ele.top, ele.width, ele.height);
});코드 동작 원리
위 예제의 핵심 흐름은 다음과 같습니다.
1. 좌표 보정: event.pageX, event.pageY 값은 문서 전체 기준의 좌표이므로, 캔버스의 offsetLeft와 offsetTop 값을 빼주어 캔버스 내부 기준의 상대 좌표(xVal, yVal)를 구합니다.
2. 영역 판정: 클릭 좌표가 특정 도형의 top ~ top+height 범위이면서 동시에 left ~ left+width 범위 안에 있다면, 해당 도형이 클릭된 것으로 판단합니다.
3. 도형 관리: 클릭 판정이 필요한 도형들은 elements 배열에 위치와 크기 정보를 담아 관리하며, 같은 배열 데이터를 사용해 실제로 캔버스에 그립니다.
이 방식을 응용하면 여러 개의 도형에 서로 다른 클릭 동작을 연결하거나, 마우스 오버(hover) 효과를 구현하는 등 캔버스 기반 인터랙티브 UI를 손쉽게 만들 수 있습니다.