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

HTML5 캔버스에서 베지어 경로 도형의 클릭 감지하기

HTML5 캔버스에서 베지어 경로 도형의 클릭 감지 방법

HTML5 캔버스에서는 isPointInPath() 메서드 대신 픽셀 데이터 기반 충돌 검사를 사용하여 베지어(Bezier) 경로로 그려진 복잡한 도형의 클릭 여부를 정확하게 판별할 수 있습니다.

핵심 원리는 다음과 같습니다.

  • 각 도형을 임시(고스트) 캔버스 컨텍스트에 하나씩 그립니다.
  • getImageData()를 사용해 마우스 클릭 좌표에 해당하는 픽셀 1개의 데이터를 읽어옵니다.
  • 픽셀의 알파 채널 값(투명도)이 0보다 크면, 해당 위치에 도형이 존재한다는 의미이므로 클릭된 것으로 판단합니다.

예제 코드

var l = boxes.length;
for (var i = l-1; i >= 0; i--) {
    // 현재 도형을 고스트 컨텍스트에 그리기
    drawshape(gctx, boxes[i], 'black', 'black');

    // 클릭 좌표(mx, my)의 픽셀 1개 데이터 가져오기
    var imgData = gctx.getImageData(mx, my, 1, 1);
    var index = (mx + my * imgData.width) * 4;

    // 알파 채널(data[3])이 0보다 크면 도형 위를 클릭한 것
    if (imgData.data[3] > 0) {
        mySel = boxes[i];
        offsetx = mx - mySel.x;
        offsety = my - mySel.y;
        mySel.x = mx - offsetx;
        mySel.y = my - offsety;
        isDrag = true;
        canvas.onmousemove = myMove;
        invalidate();
        clear(gctx);
        return;
    }
}

코드 동작 설명

1. 역순 순회boxes 배열을 뒤에서부터 탐색하므로, 나중에 그려져 화면상 가장 위에 있는 도형을 우선적으로 감지합니다.

2. 픽셀 인덱스 계산(mx + my * imgData.width) * 4 공식으로 클릭 지점 픽셀의 배열 내 위치를 구합니다. 각 픽셀은 R, G, B, A 순서의 4바이트로 저장되므로 4를 곱합니다.

3. 알파 값 검사imgData.data[3]은 알파(투명도) 채널입니다. 이 값이 0보다 크면 클릭한 지점에 도형이 그려져 있다는 뜻이며, 즉시 해당 도형을 선택 객체(mySel)로 지정하고 드래그 상태로 전환한 뒤 함수를 종료합니다.

참고 사항

도형 개수가 많으면 매번 전체를 다시 그리며 검사하는 방식은 성능 부담이 될 수 있습니다. 이 경우 오프스크린 캔버스에 도형 ID별 색상을 미리 렌더링해 두고, 클릭 시 색상만 조회하는 컬러 피킹(color picking) 기법을 함께 고려하면 효율적입니다.