Javascript로 디바이스 방향 정보 다루기

펄핏 Perfitt·2022년 5월 26일
3
post-thumbnail

안녕하세요. Perfitt에서 프론트엔드 개발자로 일하고 있는 chloe입니다.
자바스크립트 이벤트 중에 디바이스의 방향 정보를 다루는 Device Orientation 이벤트를 들어보신 적이 있으신가요? 저는 이번에 핸드폰이 좌우로 움직이는 방향에 따라 버튼을 움직이는 기능을 구현했어야 했는데요~! 자바스크립트 Device orientation 이벤트를 활용해 구현하였습니다~ 저와 비슷한 기능을 구현해야 하는 개발자 분들에게 조금이라도 도움이 되었으면 하는 마음에서 글을 적어봅니다. 🙂

Roll, Yaw, Pitch란?

디바이스 방향 정보에 대한 이해도를 높이기 위해 roll, yaw, pitch 에 대한 개념을 먼저 알아보겠습니다.

특정 물체가 움직이는 경우, 어떤 외부 요인에 의해 움직이는 물체는 이동하려는 목표 대비 오차(Error) 가 발생하게 됩니다. 이 오차가 발생하게 되는 원인으로 바로 roll, yaw, pitch 가 있습니다.

Roll : xx축을 중심으로 회전하는 것
Yaw : zz축을 중심으로 회전하는 것
Pitch : yy축을 중심으로 회전하는 것

자세한 이해를 위해 아래를 참고해주세요~!

roll, yaw, pitch 에 대해 더 자세히 알고 싶으시다면 여기를 참고해주세요~

이 개념을 디바이스에 적용해서보면 아래 그림과 같습니다.


디바이스 방향 변화를 다루는 DeviceOrientationEvent

위 개념을 이제 알았으니, 디바이스 방향 변화를 다루는 자바스크립트 이벤트 DeviceOrientationEvent 에 대해 더 자세히 설명해보겠습니다~!

디바이스의 방향 변화는 3개 각도(alpha, beta, gamma) 를 이용해 측정됩니다. deviceorientation 이벤트에 리스너를 등록하면 디바이스의 방향 데이터에 접근할 수 있습니다.

아래 코드를 참고해주세요.

window.addEventListener('deviceorientation',handleOrientation);
function handleOrientation(event) {
	const { alpha, beta, gamma } = event;
}

alpha : zz축을 중심으로 0도부터 360도까지 범위에 대한 디바이스의 움직임을 나타냅니다.
(yaw 값과 같음)
beta : xx축을 중심으로 -180도부터 180도(모바일 사파리: -90도 ~ 90도) 까지 범위에 대한 디바이스의 움직임을 나타냅니다. 디바이스의 앞뒤 움직임을 나타낸다고 볼 수 있습니다.
(pitch 값과 같음)
gamma : yy축을 중심으로 -90도부터 90도(모바일 사파리: -180도 ~ 180도) 까지 범위에 대한 디바이스의 움직임을 나타냅니다. 디바이스의 좌우 움직임을 나타낸다고 볼 수 있습니다.
(roll 값과 같음)


디바이스 좌우 움직임에 대한 값(gamma) 을 활용한 예시

저는 아래 이미지에서 맨 아래에 위치한 가로로 긴 바에 있는 버튼이 디바이스 방향에 따라 좌우로 움직이게 해줘야 했습니다.
그리고 이 버튼이 초록색 부분으로 이동해야 다음으로 동작이 가능하게 구현하였습니다.

React Hooks를 활용해 개발한 코드 일부분을 잠깐 보면..

const [orientation, setOrientation] = useState({ gamma: 0 });

orientation 값이 변경되면 orientation.gamma 는 deviceorientaion 이벤트의 gamma 값을 바라봅니다.

기울기 바 안에서만 버튼이 움직이게 해야했고, gamma 값에 따라 위의 하얀색 버튼이 좌우로 움직이게 됩니다.

이를 편리하게 계산하기 위해서 정규화 공식을 사용해 값을 계산했습니다.

정규화 공식 활용

정규화는 다음과 같은 공식을 사용해서 특성 값의 범위를 [0, 1] 로 옮깁니다.

X1=XXminXmaxXminX^1 = \frac{X - Xmin}{Xmax - Xmin}

저는 마니님의 도움을 받아 아래와 같이 함수를 만들어서 적용해주었습니다!

const SIDE_MIN = -50;
const SIDE_MAX = 50;

const normalizedValue = useMemo(() => {
	if (!orientation || !orientation.gamma) return 0.5;
	let computedGamma = orientation.gamma;
	if (computedGamma < SIDE_MIN) computedGamma = SIDE_MIN;
	if (computedGamma > SIDE_MAX) computedGamma = SIDE_MAX;

	return (computedGamma - SIDE_MIN) / (SIDE_MAX - SIDE_MIN);
}, [orientation]);

DeviceOrientationEvent 활용 결과 화면

최종적으로, validation (ex) - 40 ≤ { roll || gamma } ≤ -20) 을 지정해주어서 orientation.gamma 값이 초록색 범위에 있을 때 다음 화면으로 넘어가서 촬영이 가능하도록 구현하였습니다-!

아래화면을 참고해주세요!

핸드폰을 좌우로 움직이면 하얀색 원형 버튼이 좌우로 움직이게 됩니다.


마치며

이번에 처음으로 디바이스 방향 정보를 다루는 이벤트를 활용해 개발해보았는데요! 이런 이벤트가 있구나 신기하기도 했고 디바이스 움직임에 따라 값이 달라지는게 재미있기도 했습니다. :)

Device Orientation 이벤트를 활용해보고 싶으신 분들에게 도움이 조금이라도 되길 바라며 이만 글을 마칩니다.

Reference

profile
Beyond The Size Limit

0개의 댓글