소개
스마트폰 및 태블릿과 같은 휴대기기에는 일반적으로 사용자의 손가락으로 이루어진 상호작용을 캡처하는 정전식 터치 감지 화면이 있습니다. 모바일 웹이 발전하면서 점점 정교한 애플리케이션을 사용할 수 있게 됨에 따라 웹 개발자는 이러한 이벤트를 처리할 방법이 필요합니다. 예를 들어 거의 모든 속도감 있는 게임에서는 플레이어가 한 번에 여러 버튼을 눌러야 하는데, 이는 터치 스크린의 맥락에서 멀티터치를 의미합니다.
Apple은 iOS 2.0에서 터치 이벤트 API를 도입했습니다. Android는 이 사실상의 표준을 따라잡고 격차를 좁히고 있습니다. 최근 W3C 워킹 그룹이 이 터치 이벤트 사양을 연구하기 위해 모였습니다.
이 도움말에서는 iOS 및 Android 기기와 터치를 지원하는 하드웨어의 데스크톱 Chrome에서 제공하는 터치 이벤트 API를 자세히 살펴보고, 빌드할 수 있는 애플리케이션 유형을 살펴보고, 몇 가지 권장사항을 제시하고, 터치 지원 애플리케이션을 더 쉽게 개발할 수 있는 유용한 기법을 다룹니다.
터치 이벤트
사양에 설명된 세 가지 기본 터치 이벤트는 휴대기기 전반에 걸쳐 광범위하게 구현됩니다.
- touchstart: 손가락이 DOM 요소에 배치됩니다.
- touchmove: DOM 요소를 따라 손가락을 드래그합니다.
- touchend: DOM 요소에서 손가락을 삭제합니다.
각 터치 이벤트에는 세 개의 터치 목록이 포함됩니다.
- touches: 현재 화면에 있는 모든 손가락의 목록입니다.
- targetTouches: 현재 DOM 요소의 손가락 목록입니다.
- changedTouches: 현재 이벤트와 관련된 손가락 목록입니다. 예를 들어 touchend 이벤트에서는 삭제된 손가락이 됩니다.
이러한 목록은 터치 정보를 포함하는 객체로 구성됩니다.
- 식별자: 터치 세션에서 현재 손가락을 고유하게 식별하는 숫자입니다.
- target: 작업의 타겟이었던 DOM 요소입니다.
- 클라이언트/페이지/화면 좌표: 화면에서 작업이 발생한 위치입니다.
- 반경 좌표 및 회전 각도: 손가락 모양을 근사하는 타원을 나타냅니다.
터치 지원 앱
touchstart, touchmove 및 touchend 이벤트는 손가락 모으기, 확대/축소, 회전 등의 일반적인 멀티 터치 동작을 비롯하여 거의 모든 종류의 터치 기반 상호작용을 지원하기에 충분한 기능 세트를 제공합니다.
이 스니펫을 사용하면 한 손가락 터치를 사용하여 DOM 요소를 드래그할 수 있습니다.
var obj = document.getElementById('id');
obj.addEventListener('touchmove', function(event) {
// If there's exactly one finger inside this element
if (event.targetTouches.length == 1) {
var touch = event.targetTouches[0];
// Place element where the finger is
obj.style.left = touch.pageX + 'px';
obj.style.top = touch.pageY + 'px';
}
}, false);
다음은 화면의 모든 현재 터치를 표시하는 샘플입니다. 기기의 응답성을 파악하는 데 유용합니다.
// Setup canvas and expose context via ctx variable
canvas.addEventListener('touchmove', function(event) {
for (var i = 0; i < event.touches.length; i++) {
var touch = event.touches[i];
ctx.beginPath();
ctx.arc(touch.pageX, touch.pageY, 20, 0, 2*Math.PI, true);
ctx.fill();
ctx.stroke();
}
}, false);
데모
Paul Irish 등이 만든 이 캔버스 기반 그리기 데모와 같이 이미 여러 가지 흥미로운 멀티 터치 데모가 있습니다.
그리고 CSS3 변환 및 전환과 캔버스를 사용하는 Fruit Ninja 클론인 기술 데모인 브라우저 닌자도 있습니다.
권장사항
확대/축소 방지
스와이프 및 동작이 스크롤 및 확대/축소와 같은 브라우저 동작과 연결되는 경우가 많으므로 기본 설정은 멀티 터치에 적합하지 않습니다.
확대/축소를 사용 중지하려면 다음 메타 태그를 사용하여 사용자가 크기를 조절할 수 없도록 뷰포트를 설정하세요.
<meta name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no>
뷰포트 설정에 관한 자세한 내용은 이 모바일 HTML5 도움말을 참고하세요.
스크롤 방지
일부 휴대기기에는 스크롤이 콘텐츠 경계를 초과하면 뷰가 뒤로 튀어 오는 기존 iOS 오버스크롤 효과와 같은 touchmove의 기본 동작이 있습니다. 이는 많은 멀티 터치 애플리케이션에서 혼동을 야기하며 쉽게 사용 중지할 수 있습니다.
document.body.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);
렌더링 주의
복잡한 다중 손가락 동작이 포함된 멀티 터치 애플리케이션을 작성하는 경우 한 번에 여러 터치 이벤트를 처리해야 하므로 터치 이벤트에 반응하는 방식에 주의해야 합니다. 이전 섹션의 샘플을 생각해 보세요. 이 샘플은 화면에 모든 터치를 그립니다. 터치 입력이 발생하는 즉시 그릴 수 있습니다.
canvas.addEventListener('touchmove', function(event) {
renderTouches(event.touches);
}, false);
그러나 이 기법은 화면의 손가락 수에 따라 확장되지 않습니다. 대신 모든 손가락을 추적하고 루프로 렌더링하여 훨씬 더 나은 성능을 얻을 수 있습니다.
var touches = []
canvas.addEventListener('touchmove', function(event) {
touches = event.touches;
}, false);
// Setup a 60fps timer
timer = setInterval(function() {
renderTouches(touches);
}, 15);
targetTouches 및 changedTouches 사용
event.touches는 DOM 요소의 타겟에 있는 손가락뿐만 아니라 화면에 닿는 모든 손가락의 배열입니다. 대신 event.targetTouches 또는 event.changedTouches를 사용하는 것이 훨씬 더 유용할 수 있습니다.
마지막으로 모바일용으로 개발 중이므로 에릭 비델만의 도움말과 이 W3C 문서에 설명된 일반적인 모바일 권장사항을 알아야 합니다.
기기 지원
안타깝게도 터치 이벤트 구현은 완전성과 품질이 크게 다릅니다. 지원되는 이벤트, touchmove 실행 해상도 등 터치 API 구현에 관한 몇 가지 기본 정보를 표시하는 진단 스크립트를 작성했습니다. Nexus One 및 Nexus S 하드웨어에서 Android 2.3.3, Xoom에서 Android 3.0.1, iPad 및 iPhone에서 iOS 4.2를 테스트했습니다.
간단히 말해 테스트한 모든 브라우저는 touchstart, touchend, touchmove 이벤트를 지원합니다.
사양에서 세 가지 터치 이벤트를 추가로 제공하지만 테스트를 통해 확인된 브라우저에서 지원하지 않습니다.
- touchenter: 움직이는 손가락이 DOM 요소에 진입합니다.
- touchleave: 움직이는 손가락이 DOM 요소를 벗어납니다.
- touchcancel: 터치가 중단됩니다 (구현에 따라 다름).
각 터치 목록 내에서 테스트된 브라우저는 touches, targetTouches, changedTouches 터치 목록도 제공합니다. 그러나 테스트한 브라우저 중 화면을 터치하는 손가락의 모양을 지정하는 radiusX, radiusY 또는 rotationAngle을 지원하는 브라우저는 없습니다.
터치 이동 중에 이벤트는 테스트된 모든 기기에서 초당 약 60회 실행됩니다.
Android 2.3.3(Nexus)
Android Gingerbread 브라우저 (Nexus One 및 Nexus S에서 테스트됨)에서는 멀티터치가 지원되지 않습니다. 이는 알려진 문제입니다.
Android 3.0.1(Xoom)
Xoom의 브라우저에는 기본 멀티 터치가 지원되지만 단일 DOM 요소에서만 작동합니다. 브라우저가 서로 다른 DOM 요소에서 동시에 두 번 터치하는 것에 올바르게 응답하지 않습니다. 즉, 다음은 두 개의 동시 터치에 반응합니다.
obj1.addEventListener('touchmove', function(event) {
for (var i = 0; i < event.targetTouches; i++) {
var touch = event.targetTouches[i];
console.log('touched ' + touch.identifier);
}
}, false);
다음은 지원되지 않습니다.
var objs = [obj1, obj2];
for (var i = 0; i < objs.length; i++) {
var obj = objs[i];
obj.addEventListener('touchmove', function(event) {
if (event.targetTouches.length == 1) {
console.log('touched ' + event.targetTouches[0].identifier);
}
}, false);
}
iOS 4.x (iPad, iPhone)
iOS 기기는 멀티 터치를 완벽하게 지원하고, 꽤 많은 손가락을 추적할 수 있으며, 브라우저에서 반응이 빠른 터치 환경을 제공합니다.
개발자 도구
모바일 개발에서는 데스크톱에서 프로토타입을 만든 다음 지원하려는 기기에서 모바일 관련 부분을 처리하는 것이 더 쉬울 때가 많습니다. 멀티터치는 대부분의 PC에는 터치 입력이 없기 때문에 PC에서 테스트하기 어려운 기능 중 하나입니다.
모바일에서 테스트해야 하면 개발 주기가 길어질 수 있습니다. 변경사항을 서버에 푸시한 후 기기에 로드해야 하기 때문입니다. 그런 다음 실행되면 태블릿과 스마트폰에는 웹 개발자 도구가 없으므로 애플리케이션을 디버그하기 위해 할 수 있는 일이 거의 없습니다.
이 문제를 해결하려면 개발 머신에서 터치 이벤트를 시뮬레이션하면 됩니다. 단일 터치의 경우 마우스 이벤트를 기반으로 터치 이벤트를 시뮬레이션할 수 있습니다. 최신 Apple MacBook과 같이 터치 입력이 있는 기기가 있으면 멀티 터치 이벤트를 시뮬레이션할 수 있습니다.
원터치 이벤트
데스크톱에서 싱글 터치 이벤트를 시뮬레이션하려면 Chrome의 개발자 도구에서 터치 이벤트 에뮬레이션을 사용하세요. 개발자 도구를 연 다음 설정 톱니바퀴를 선택하고 '재정의' 또는 '에뮬레이션'을 선택한 다음 '터치 이벤트 에뮬레이션'을 사용 설정합니다.
다른 브라우저의 경우 페이지에서 터치 이벤트를 시뮬레이션하고 거대한 손을 제공하는 Phantom Limb를 사용해 보세요.
여러 플랫폼에서 터치 및 마우스 이벤트를 통합하는 Touchable jQuery 플러그인도 있습니다.
멀티 터치 이벤트
멀티터치 트랙패드 (예: Apple MacBook 또는 MagicPad)의 브라우저에서 멀티터치 웹 애플리케이션이 작동하도록 하기 위해 MagicTouch.js polyfill을 만들었습니다. 트랙패드에서 터치 이벤트를 캡처하여 표준 호환 터치 이벤트로 변환합니다.
- npTuioClient NPAPI 플러그인을 다운로드하여 ~/Library/Internet Plug-Ins/에 설치합니다.
- Mac의 MagicPad용 TongSeng TUIO 앱을 다운로드하고 서버를 시작합니다.
- npTuioClient 콜백을 기반으로 사양 호환 터치 이벤트를 시뮬레이션하는 자바스크립트 라이브러리인 MagicTouch.js를 다운로드합니다.
- 다음과 같이 애플리케이션에 magictouch.js 스크립트와 npTuioClient 플러그인을 포함합니다.
<head>
...
<script src="/path/to/magictouch.js"></script>
</head>
<body>
...
<object id="tuio" type="application/x-tuio" style="width: 0px; height: 0px;">
Touch input plugin failed to load!
</object>
</body>
플러그인을 사용 설정해야 할 수 있습니다.
magictouch.js를 사용한 라이브 데모는 paulirish.com/demo/multi에서 확인할 수 있습니다.
이 접근 방식은 Chrome 10에서만 테스트했지만 약간의 조정만으로 다른 최신 브라우저에서도 작동합니다.
컴퓨터에 멀티 터치 입력이 없는 경우 reacTIVision과 같은 다른 TUIO 추적기를 사용하여 터치 이벤트를 시뮬레이션할 수 있습니다. 자세한 내용은 TUIO 프로젝트 페이지를 참고하세요.
동작이 OS 수준 멀티 터치 동작과 동일할 수 있습니다. OS X에서는 시스템 환경설정의 트랙패드 환경설정 창으로 이동하여 시스템 전체 이벤트를 구성할 수 있습니다.
모바일 브라우저에서 멀티 터치 기능이 점점 더 광범위하게 지원됨에 따라 새로운 웹 애플리케이션에서 이 풍부한 API를 최대한 활용하게 될 것을 기대합니다.