IT기타

태블릿(모바일)용 크롬 확장프로그램 개발 : 터치펜 입력 감지

emilyyoo 2025. 1. 30. 12:06
728x90

태블릿(모바일)용 크롬 확장프로그램 개발ㅇㄴ

https://betterwe.tistory.com/302

 

태블릿(모바일)용 크롬 확장프로그램 개발(스크롤, touch처리, html5, canvas)

개발 목적태블릿의 웹페이지 위에서 드로잉하기 계기예전에 웹사이트 구축이 많지 않았던 시절, 종이로만 긴 글이나 신문기사를 읽는게 당연했다. 그때, 나는 중요 부분에 밑줄을 긋거나 동그

betterwe.tistory.com

 

위의 포스팅에서 터치 기기(특히 태블릿) 에서 웹 페이지 위에 그림을 그릴 수 있는 확장 프로그램 개발했던 것을 정리했었다. 

 

이번에는 위의 글에서 개발했던 프로그램을 개선했던 것을 기록하려고 한다. 

 

 

일단 1차 개발에서는 그리기 모드를 키고 껐을 때 기능이 정상작동하는 것에 초점을 맞췄었다. 

 

그래서 그리기 모드를 키고 끄는 것을 팝업창에 버튼으로 했었다. 사용에 너무 불편하고 이상하다.

 

**문제

 

수시로 왔다갔다 적용해야하는 기능들을 팝업창을 뜨게 버튼을 누르고 또 그 안에 있는 버튼을 누르는 방식은 너무 불편하고 기기의 특성을 고려하지 않는 UI다. 

 

**개발해야 할 사항

 

터치기기의 특성을 고려하고, 편하게 사용 할 수 있도록 

 

터치펜(스타일러스) 입력일 때는 그리기 모드 활성화,

손가락 터치일 때는 비활성화하는 기능을 만들기로 했다.

 

그래서 터치팬으로 밑줄 긋고 메모하다가 내용을 더 보려면 손가락으로 스크롤을 내리는 방식으로 작동하게 끔. 

 

**구현

1. Pointer Events API 사용 

 

Pointer Events API를 사용하여 스타일러스(터치펜) 입력을 감지했다.

 

Pointer Events API는 하나의 이벤트(pointerdown, pointermove, pointerup)에서

마우스, 터치, 스타일러스 입력을 모두 통합하여 감지할 수 있다. 

 

또한 스타일러스 입력에서 필압(pressure) 및 기울기(tilt) 도 함께 제공한다.

 

 

handlePointerDown(), handlePointerMove(), handlePointerUp()

 

-> 내 코드에서는 이런 이벤트 핸들러가 스타일러스 입력을 처리한다.

 

2. 터치펜 감지 및 선 그리기 과정

// 이벤트 리스너 등록
document.addEventListener("pointerdown", handlePointerDown);
document.addEventListener("pointermove", handlePointerMove);
document.addEventListener("pointerup", handlePointerUp);

 

 

📌 (1) 스타일러스 터치 시작 감지

 
function handlePointerDown(e) {
    if (!isExtensionEnabled || !isDrawingMode || !canvas) return;
    
    isDrawing = true;

    const isBodyContainer = !targetContainer || targetContainer === document.body;
    
    if (isBodyContainer) {
        lastX = e.clientX + window.scrollX;
        lastY = e.clientY + window.scrollY;
    } else {
        const rect = canvas.getBoundingClientRect();
        lastX = e.clientX - rect.left;
        lastY = e.clientY - rect.top;
    }
}

🔹 설명:

  • pointerdown 이벤트가 발생하면 스타일러스 입력을 시작한 좌표를 기록 (lastX, lastY).
  • 스크롤 위치를 반영하여 절대 좌표로 변환.

📌 (2) 스타일러스 이동 감지 & 필압(Pressure) 적용

function handlePointerMove(e) {
    if (!isExtensionEnabled || !isDrawingMode || !isDrawing || !canvas) return;
    
    e.preventDefault(); 

    const pressure = e.pressure || 0.5;
    const lineWidth = pressure * currentLineWidth * 2;

    const isBodyContainer = !targetContainer || targetContainer === document.body;
    let currentX, currentY;

    if (isBodyContainer) {
        currentX = e.clientX;
        currentY = e.clientY;
        
        const distance = Math.hypot(
            (currentX + window.scrollX) - lastX,
            (currentY + window.scrollY) - lastY
        );
        
        if (distance > 100) {
            lastX = currentX + window.scrollX;
            lastY = currentY + window.scrollY;
            return;
        }

        ctx.beginPath();
        ctx.moveTo(lastX - window.scrollX, lastY - window.scrollY);
        ctx.lineTo(currentX, currentY);
        ctx.strokeStyle = currentColor;
        ctx.lineWidth = lineWidth;
        ctx.lineCap = 'round';
        ctx.stroke();
        
        drawings.push({
            startX: lastX,
            startY: lastY,
            endX: currentX + window.scrollX,
            endY: currentY + window.scrollY,
            color: currentColor,
            lineWidth: lineWidth,
            isBodyContainer: isBodyContainer
        });

        lastX = currentX + window.scrollX;
        lastY = currentY + window.scrollY;
    }
}

🔹 설명:

  1. e.pressure 값을 이용하여 필압(pressure)에 따라 선 두께 조정.
    • pressure 값은 0.0 (가벼운 터치) ~ 1.0 (강한 터치) 사이 값
    • 기본적으로 0.5를 최소값으로 설정
  2. Math.hypot()를 사용하여 스타일러스의 이동 거리를 계산하고,
    • 이동 거리가 100px 이상이면 선을 그리지 않음 (빠른 손 움직임 방지).
  3. ctx.beginPath()를 사용해 이전 좌표에서 현재 좌표까지 선을 그림.
  4. drawings 배열에 그린 선 데이터를 저장하여 다시 그릴 때 사용.

 

 

📌 (3) 스타일러스 떼기 감지

js
function handlePointerUp(e) {
    isDrawing = false;
}

🔹 설명:

  • 스타일러스를 떼면 isDrawing = false로 설정하여 그림을 멈춘다.

 

 

 

 

728x90