태블릿(모바일)용 크롬 확장프로그램 개발ㅇㄴ
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;
}
}
🔹 설명:
- e.pressure 값을 이용하여 필압(pressure)에 따라 선 두께 조정.
- pressure 값은 0.0 (가벼운 터치) ~ 1.0 (강한 터치) 사이 값
- 기본적으로 0.5를 최소값으로 설정
- Math.hypot()를 사용하여 스타일러스의 이동 거리를 계산하고,
- 이동 거리가 100px 이상이면 선을 그리지 않음 (빠른 손 움직임 방지).
- ctx.beginPath()를 사용해 이전 좌표에서 현재 좌표까지 선을 그림.
- drawings 배열에 그린 선 데이터를 저장하여 다시 그릴 때 사용.
📌 (3) 스타일러스 떼기 감지
🔹 설명:
- 스타일러스를 떼면 isDrawing = false로 설정하여 그림을 멈춘다.
'IT기타' 카테고리의 다른 글
fastAPI, postgre DB 연결 설정 (0) | 2025.02.04 |
---|---|
Supabase에서 데이터베이스 비밀번호 변경 (0) | 2025.02.04 |
태블릿(모바일)용 크롬 확장프로그램 개발(스크롤, touch처리, html5, canvas) (0) | 2025.01.25 |
git repository 생성 및 소스 반영 (0) | 2025.01.22 |
한꺼번에 여러 웹사이트를 열려면 (0) | 2024.12.26 |