[Next.js]모바일 웹 브라우저에서 deviceMotionEvent로 기기의 움직임 가져오기

Designated Hitter Jack·2023년 11월 28일
0

SW 사관학교 정글

목록 보기
43/44
post-thumbnail

개발하려고 했던 것

현재 나는 SW사관학교 정글의 마지막 과정인 나만의 무기 만들기 중이다.
이전 블로그 포스트에서 어느정도 언급했는지는 모르지만, 우리가 만들려고 하는 주제는 1:多 레크리에이션 웹 서비스이다. 그 첫번째 게임인 그림 맞추기(캐치마인드)는 꽤 훌륭한 완성도를 가지고 개발이 마무리 되었다.

그리고 우리는 우리가 만드는 서비스의 핵심이자 메인 기능인 무궁화 꽃이 피었습니다 개발을 시작했다.
무궁화~를 완성하기 위해서 가장 중요한 기능은 사용자가 핸드폰을 흔들면, 그 흔든 정도를 웹 브라우저 페이지에서 측정하여 서버로 보내는 것이라고 할 수 있다. 이 기능을 진지하게 구현하려고 하기 전 까진 '이렇게 짜면 되지 않을까?'라고 안일하게 생각했지만, 생각보다 (한국어) 자료가 부족했다.
이에 더해 Safari 13 이상 버전에서는 Device에서 움직임이나 방향을 감지하기 위해선 이용자의 허가를 요청하는 것이 필수였으므로 이에 대해서도 많은 자료를 찾아보았고, 지금까지 공부한 것을 잊어버리기 전에 한 번 정리해두려고 한다.

DeviceMotionEvent

MDN 공식문서

공식문서에서도 확인할 수 있는 DeviceMotionEvent(DeviceOrientationEvent 역시 마찬가지)를 지원하는 브라우저의 목록들이다. 보면 requestPermission()이라는 함수를 유일하게 지원하는 브라우저는 Safari 뿐인 것을 알 수 있다. Safari는 13 버전 이후부터 사용자가 device로부터 가속도나 방향을 읽어오기 위해서 명시적인 사용자의 허가를 요구한다. 그 허가를 요구하는 함수가 바로 requestPermission이다.

requestPermission으로 Safari 구분하기

//safari 13 이상의 safari 브라우저에서는 모션 이벤트 권한을 요청해야 함
    const isSafariOver13 = typeof window.DeviceOrientationEvent.requestPermission === 'function';

이 코드를 이용하면 현재 사용하고 있는 브라우저가 사파리인지 아닌지를 구분할 수 있다. 원리는 사파리를 제외한 다른 모든 브라우저나 컴파일러(VScode 포함!)에서는 이 함수를 사용하지 않으므로 이 함수의 타입을 'function'으로 보는지 아닌지 여부에 따라 사파리와 다른 브라우저를 구분할 수 있는 것 같다.

vscode도 빨간줄이 좍좍

적용하면 이런식으로 alert 창이 뜨는데 주의해야 할 점이 두가지 있다.
첫번째는 해당 함수는 useEffect를 사용하여 페이지 진입과 동시에 실행하도록 적용할 수 없다. 무조건 유저가 버튼을 누르거나 하는 상호작용을 통해서만 실행시킬 수 있다.
두번째로는 만약 유저가 실수로든 일부러든 취소를 눌렀다면 사파리를 완전히 끈 후 다시 실행시키기 전 까지 requestPermission을 다시 실행시킬 방법이 없다는 것이다.

그리고 참고할 부분으로는 deviceMotionEvent로 requestPermission을 불러오든 deviceOrientationEvent로 requestPermission을 불러오든 상관없다. 둘 중 하나로라도 허용을 받았으면 방향(orientation)이나 가속도(motion)측정 둘 다 사용할 수 있다.

deviceMotionEvent 함수 적용하기

const requestPermissionSafari = () => {
        if (isSafariOver13) {
            window.DeviceOrientationEvent.requestPermission().then((permissionState) => {
                if (permissionState === 'denied') {
                    //safari 브라우저를 종료하고 다시 접속하도록 안내하는 화면 필요
                    alert('게임에 참여 하려면 센서 권한을 허용해주세요. Safari를 완전히 종료하고 다시 접속해주세요.');
                  return;
                } else if (permissionState === 'granted') {
                    window.addEventListener('devicemotion', handleDeviceMotion);
                };
            })
        }          
    }

이렇게 사용자의 browser가 safari인지 아닌지를 구분한 후 deviceMotion을 통해 기기의 움직임을 추적할 수 있다.

window.addEventListener('devicemotion' 또는 'deviceorientation', 사용하려는 함수)

라는 함수를 통해 사용할 수 있다.
사용자의 device가 Android만 접속할 것이 확실한 상황이라면 위에서 쓴 복잡한 함수 없이 딱 이 한줄만 있으면 되나...Safari가 저 모양인 걸 누굴 탓하리

profile
Fear always springs from ignorance.

0개의 댓글