[TypeScript] 제스처로 대화하기. #6 - 롱 프레스(with. 범위) 편
Table of contents
이번 편은 이전 편으로부터 이어집니다.
거리 계산은 지난 편의 내용으로 쉽게 구현할 수 있습니다. 하지만 한 가지 차이점은 탭의 경우, 이벤트 핸들러에서 처리하기 때문에 쉽게 좌표를 받아올 수 있지만 롱 프레스의 경우에는 그렇지 못하다는 것입니다. 현재 구현에서도 pointerdown
의 좌표를 받아올 수 있지만 목적에 부합하지 않습니다. 필요한 것은 타이머가 호출된 시점의 좌표입니다.
타이머 호출 시점의 좌표를 받아오려면 어떻게 해야 할까요? 이를 위해서는 좌표의 변경을 실시간으로 추적할 필요가 있습니다. 이를 위해 본 포스트에서는 pointermove
를 사용할 것입니다.
interface Point {
x: number;
y: number;
}
let currPoint: Point;
element.addEventListener("pointermove", e => {
currPoint = { x: e.clientX, y: e.clientY };
});
currPoint
는 현재 좌표를 의미하며, 최초에 pointerdown
에서 초기화해야 합니다. 이후 pointermove
를 통해 실시간으로 좌표를 갱신합니다. 이렇게 하면 타이머 콜백에서 currPoint
를 현재 좌표로써 사용할 수 있습니다.
포인터의 두 가지 상황
포인터 캡처의 여부에 따라 상황은 달라집니다. 포인터가 캡처된 경우, pointermove
는 요소 외부의 변화도 감지합니다. 그렇지 않은 경우, pointermove
는 요소 내부에 대해서만 작동합니다. 하지만 그 대신 pointerleave
를 통해 포인터가 요소 외부로 이탈했음을 확인할 수 있습니다.
명시적으로 포인터를 캡처하거나 해제하여 하나의 상황만 발생하도록 제한할 수 있습니다. 하지만 [typescript] 포인터 대통합(with. PointerEvent)에서도 언급했듯 이는 다른 핸들러도 할 수 있습니다. 즉, 필연적으로 핸들러 간 영향을 미치게 됩니다. 이에 의존하는 것은 적절치 않으며, 의존할 경우엔 자칫 예상치 못한 버그로 이어질 수 있습니다.
그렇다면 어떻게 해야 할까요? 해결책은 두 가지 상황을 모두 고려하는 것입니다. 이는 생각보다 어렵지 않습니다. 포인터가 해제된 경우, pointermove
가 외부 좌표를 추적하지 못하는 대신 pointerleave
를 사용할 수 있습니다.
element.addEventListener("pointerleave", e => {
currPoint = { x: e.clientX, y: e.clientY };
})
pointerleave
의 좌표는 포인터가 요소 외부로 이탈한 직후에 해당하기 때문에 포인터가 캡처되지 않았다면 이후 정확한 좌표는 알 수 없습니다. 하지만 이것으로 충분할 것입니다. 요소에서 이탈하면 좌표가 얼마나 떨어져 있더라도 범위에서 이탈한 것으로 보는 것이 타당하기 때문입니다.
시리즈는 다음 편에서 계속됩니다. 읽어주셔서 감사합니다!
묻고 답하기
개인적인 판단에 의해 적절하다고 여겨지는 경우, 모두가 볼 수 있도록 이곳에 문답이 추가됩니다. 그렇지 않더라도 질문에 대한 답변은 별도로 이루어집니다.
Subscribe to my newsletter
Read articles from 고라니드로 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by