디바이스 방향 및 움직임

W3C 후보 권고안 초안,

이 문서에 대한 추가 정보
이 버전:
https://www.w3.org/TR/2025/CRD-orientation-event-20250212/
최신 공개 버전:
https://www.w3.org/TR/orientation-event/
Editor's Draft:
https://w3c.github.io/deviceorientation/
이전 버전:
히스토리:
https://www.w3.org/standards/history/orientation-event/
피드백:
public-device-apis@w3.org 제목에 “[orientation-event] … 메시지 주제 …” 포함 (아카이브)
디바이스 방향 및 움직임 저장소
구현 보고서:
https://wpt.fyi/results/orientation-event
편집자:
Reilly Grant (Google LLC)
Marcos Cáceres (Apple Inc.)
이전 편집자:
Raphael Kubo da Costa (Intel Corporation)
Rich Tibbett (Opera Software ASA)
Tim Volodine (Google Inc)
Steve Block (Google Inc 2012년 7월까지)
Andrei Popescu (Google Inc 2012년 7월까지)

요약

이 명세는 호스트 디바이스의 물리적 방향과 움직임을 나타내는 이벤트를 정의합니다. 이러한 이벤트는 웹 애플리케이션이 방향 및 움직임 데이터를 접근할 수 있도록 제공합니다. 명세는 이 데이터의 근본적인 출처에 독립적이도록 설계되어 다양한 환경 간의 상호운용성을 달성하는 것을 목표로 합니다.

이 문서의 상태

이 섹션은 출판 시점에서 이 문서의 상태를 설명합니다. 현재 W3C 출판물 목록과 이 기술 보고서의 최신 수정본은 W3C 기술 보고서 색인 https://www.w3.org/TR/에서 확인할 수 있습니다.

이 문서는 디바이스 및 센서 워킹 그룹웹 애플리케이션 워킹 그룹에서 권고 트랙을 사용하여 후보 권고안 초안으로 발표되었습니다. 이 문서는 W3C 권고안이 되는 것을 목표로 하고 있습니다.

이 문서에 대한 의견을 남기고 싶으시다면, 명세 저장소에서 이슈를 등록해 주세요.

후보 권고안으로 출판되었다고 해서 W3C와 회원들의 지지를 의미하지는 않습니다. 후보 권고안 초안에는 워킹 그룹s이 이후 후보 권고안 스냅샷에 포함하려는 이전 후보 권고안의 변경 사항이 통합되어 있습니다. 이 문서는 초안이며 언제든지 업데이트, 대체 또는 폐기될 수 있습니다. 이 문서를 진행 중인 작업 외의 목적으로 인용하는 것은 적절하지 않습니다.

이 문서가 제안된 권고 단계에 진입하기 위한 기준은 명세의 모든 기능을 독립적으로 구현하는 두 개 이상의 상호운용 가능한 사용자 에이전트가 있어야 하며, 워킹 그룹s이 개발한 테스트 스위트를 통과함으로써 확인됩니다. 워킹 그룹s은 진행 상황을 추적하기 위해 구현 보고서를 준비할 것입니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C는 각 그룹의 산출물과 관련된 공개 특허 공개 목록(디바이스 및 센서)공개 특허 공개 목록(웹 애플리케이션)을 유지 관리합니다. 이 페이지에는 특허 공개 방법에 대한 안내도 포함되어 있습니다. 실제로 필수 청구권이 포함된 특허를 알고 있는 개인은 필수 청구권에 따라 W3C 특허 정책 6항에 따라 정보를 공개해야 합니다.

일반적인 워킹 그룹 공지, 행정 및 비기술적 사항은 public-device-apis@w3.org (구독, 아카이브) 또는 public-webapps@w3.org (구독, 아카이브)로 이메일을 보내주세요.

이 문서는 2023년 11월 3일 W3C 프로세스 문서에 의해 관리됩니다.

이전 후보 권고안 이후 새롭게 추가된 기능에는 퍼미션 정책 및 API 통합이 포함되어 있으며, 이제 디바이스 방향 데이터 접근을 위해 requestPermission() 을 통한 명시적 사용자 동의가 필요합니다. 좌표계 설명 및 정밀도 요구 사항이 업데이트되어 수동 지문 채취 위험을 완화하였습니다. deviceorientationabsolute 이벤트가 도입되어 절대 방향 데이터가 필요한 애플리케이션을 지원합니다 (위험 요소로 표시됨). 인터페이스는 이제 보안 컨텍스트에서만 제공되며, 보안 및 개인정보 보호 고려사항이 규범적으로 반영되었습니다. 명세는 또한 이 API의 테스트 자동화 방법도 제공합니다 (위험 요소로 표시됨). 자세한 내용은 § 10 변경사항 섹션을 참조하세요.

1. 소개

이 섹션은 규범적이지 않습니다.

이 명세는 호스트 디바이스의 물리적 방향과 움직임에 대한 정보를 획득할 수 있는 두 가지 새로운 DOM 이벤트를 제공합니다. 이벤트에서 제공되는 정보는 원시 센서 데이터가 아니라, 정보의 근본적인 출처에 독립적인 고수준 데이터입니다. 일반적인 정보 출처로는 자이로스코프, 나침반, 가속도계 등이 있습니다.

deviceorientation 이벤트는 디바이스의 물리적 방향을 나타내며, 로컬 좌표계에서 일련의 회전으로 표현됩니다.

devicemotion 이벤트는 디바이스의 가속도를 나타내며, 디바이스에서 정의된 좌표계의 직교 좌표로 표현됩니다. 또한 디바이스가 로컬 좌표계에서 회전하는 속도도 제공합니다. 실제로 가능한 경우, 이벤트는 디바이스의 질량 중심의 가속도를 제공해야 합니다.

다음 코드 예제는 이벤트의 기본적인 사용법을 보여줍니다.

deviceorientation 이벤트를 수신하도록 등록하기:
window.addEventListener("deviceorientation", event => {
  // event.alpha, event.beta, event.gamma 처리
});

// 또는...
window.ondeviceorientation = event => {
  // event.alpha, event.beta, event.gamma 처리
};
화면 상단이 서쪽을 향하도록 수평면에 평평하게 놓인 디바이스의 방향:
{
  alpha: 90,
  beta: 0,
  gamma: 0
};

나침반 방위를 얻으려면 alpha 값을 360도에서 빼면 됩니다. 디바이스를 수평면에서 회전시키면, 나침반 방위는 (360 - alpha)로 계산됩니다.

사용자가 디바이스를 손에 들고, 화면이 수직 평면에 있고 화면 상단이 위를 향하고 있는 경우, beta 값은 90이 되며, alphagamma 값에 관계없이 항상 90입니다.
alpha 도의 나침반 방위로 사용자가 디바이스를 손에 들고, 화면이 수직 평면에 있으며 화면 상단이 사용자의 오른쪽을 향할 때의 디바이스 방향:
{
  alpha: 270 - alpha,
  beta: 0,
  gamma: 90
};
devicemotion 이벤트를 수신하도록 등록하기:
window.addEventListener("devicemotion", (event) => {
  // event.acceleration, event.accelerationIncludingGravity,
  // event.rotationRate, event.interval 처리
});

// 또는...
window.ondevicemotion = (event) => {
  // event.acceleration, event.accelerationIncludingGravity,
  // event.rotationRate, event.interval 처리
};
화면이 위를 향하도록 수평면에 평평하게 놓인 디바이스는 acceleration 값이 0이고, accelerationIncludingGravity 값은 다음과 같습니다:
{
  x: 0,
  y: 0,
  z: 9.8
};
자유 낙하 중인 디바이스(화면이 수평이고 위를 향함)는 accelerationIncludingGravity 값이 0이고, acceleration 값은 다음과 같습니다:
{
  x: 0,
  y: 0,
  z: -9.8
};
디바이스가 차량에 장착되어 있고, 화면이 수직 평면에 있으며 화면 상단이 위쪽을 향하고 차량의 뒤쪽을 향할 때, 차량이 반지름 r의 우회전을 속도 v로 주행 중이라면 디바이스는 accelerationaccelerationIncludingGravity 의 x 성분이 양수로 기록됩니다. 또한 rotationRate.gamma 값은 음수로 기록됩니다:
{
  acceleration: {x: v^2/r, y: 0, z: 0},
  accelerationIncludingGravity: {x: v^2/r, y: 9.8, z: 0},
  rotationRate: {alpha: 0, beta: 0, gamma: -v/r*180/pi}
};

2. 범위

이 섹션은 규범적이지 않습니다.

이 명세의 범위에는 호스트 디바이스의 물리적 방향 및 움직임을 나타내는 이벤트가 포함됩니다. 방향 데이터 변환 라이브러리와 같은 데이터 조작 유틸리티, 원시 센서 데이터 접근 또는 센서와 직접 인터페이스하는 방법 등은 범위에 포함되지 않습니다.

3. 모델

3.1. 디바이스 방향

이 명세는 디바이스의 물리적 방향을 구현 정의 기준 좌표계에 대한 일련의 회전으로 표현합니다.

회전 단계의 시퀀스는 Z - X' - Y'' 타입의 내적 테이트-브라이언 각([EULERANGLES])으로, 디바이스 좌표계에 적용됩니다. 이 좌표계는 [ACCELEROMETER]에 정의되어 있으며, 요약은 다음과 같습니다:

휴대폰이나 태블릿 같은 모바일 디바이스의 경우, 디바이스 좌표계는 화면의 표준 방향(일반적으로 세로)에 따라 정의됩니다. 이는 슬라이드 아웃 키보드와 같은 요소가 펼쳐지지 않고, 회전 가능한 디스플레이와 같은 요소가 기본 위치로 접혀 있는 상태를 의미합니다.

디바이스가 회전하거나 슬라이드 아웃 키보드가 펼쳐져 화면의 방향이 바뀌어도, 좌표계의 방향은 디바이스에 대해 변하지 않습니다.

노트북 컴퓨터의 경우 디바이스 좌표계는 내장 키보드를 기준으로 정의됩니다.

참고: 화면 방향 변화를 감지하려는 개발자는 [SCREEN-ORIENTATION]을 참고할 수 있습니다.

회전은 오른손 규칙을 사용하므로, 축의 양의 방향에서 볼 때 축을 따라 시계 방향으로 회전하면 양수입니다.

참고: 이 명세에서 사용하는 좌표계는 CSS Transforms 2 § 4 Transform Rendering Model과 다르며, CSS에서는 y축이 아래쪽이 양수이고 회전은 왼손 규칙을 따릅니다. 또한, rotateSelf()rotate() ( [GEOMETRY-1] 참고 )는 Z - Y' - X'' 순서로 회전을 적용하며, 이 명세의 순서와 다릅니다.

alpha, beta 그리고 gamma 로 나타내는 회전은 다음 단계로 수행됩니다:

  1. 디바이스 프레임을 z 축을 기준으로 alpha 도만큼 회전합니다. alpha 값은 [0, 360) 범위입니다.

    start orientation
    초기 위치의 디바이스로, 기준( XYZ )과 바디( xyz ) 프레임이 일치된 상태입니다.
    rotation about z axis
    디바이스가 z축을 중심으로 alpha 각도만큼 회전한 모습. 이전 x, y축 위치는 x0, y0로 표시됨.
  2. 디바이스 프레임을 x 축을 기준으로 beta 도만큼 회전합니다. beta 값은 [-180, 180) 범위입니다.

    rotation about x axis
    디바이스가 새로운 x축을 중심으로 beta 각도만큼 회전한 모습. 이전 y, z축 위치는 y0, z0로 표시됨.
  3. 디바이스 프레임을 y 축을 기준으로 gamma 도만큼 회전합니다. gamma 값은 [-90, 90) 범위입니다.

    rotation about y axis
    디바이스가 새로운 y축을 중심으로 gamma 각도만큼 회전한 모습. 이전 x, z축 위치는 x0, z0로 표시됨.

참고: 이 각도 선택은 수학적 관례를 따르지만, alpha는 나침반 방위와 반대 방향입니다. 또한 각도가 차량 동역학에서 사용되는 롤-피치-요 관례와 일치하지 않습니다.

3.1.1. 참조 좌표계 선택

디바이스의 방향은 항상 다른 좌표계에 대해 상대적으로 표현되며, 선택된 좌표계는 방향 정보의 성격과 데이터의 출처에 영향을 줍니다.

상대 디바이스 방향은 가속도계와 자이로스코프로 측정되며, 기준 좌표계는 임의적입니다. 따라서 방향 데이터는 디바이스의 초기 위치로부터의 변화를 나타냅니다.

참고: 네이티브 플랫폼 용어로는 Windows의 OrientationSensor 의 상대 센서, Android의 게임 회전 벡터 센서, 또는 Core Motion의 xArbitraryZVertical 옵션과 유사합니다.

절대 방향은 가속도계, 자이로스코프, 자기장계로 측정되며, 기준 좌표계는 지구 기준 좌표계입니다.

참고: 네이티브 플랫폼 용어로는 Windows의 OrientationSensor 의 절대 센서, Android의 회전 벡터 센서, 또는 Core Motion의 xMagneticNorthZVertical 옵션과 유사합니다.

3.2. 디바이스 움직임

이 명세는 디바이스의 공간 내 움직임을 가속도와 회전 속도로 표현하며, 이는 가속도계와 자이로스코프에서 얻어집니다. 데이터는 이전 섹션에서 요약한 디바이스 좌표계를 기준으로 제공됩니다.

가속도는 디바이스의 속도가 시간에 따라 변하는 비율입니다. 단위는 m/s2 (초당 미터 제곱)입니다.

선형 디바이스 가속도는 중력의 영향 없이 디바이스의 가속도를 나타냅니다. 디바이스가 테이블 위에 평평하게 놓여 있으면 선형 가속도 값은 0 m/s2입니다.

가속도가 중력을 포함하면, 그 값은 중력의 영향을 포함하며 고유 가속도([PROPERACCELERATION])를 나타냅니다. 디바이스가 자유 낙하 중일 때, 가속도는 0 m/s2입니다. 이는 많은 애플리케이션에서 덜 유용하지만, 자이로스코프가 없는 등의 이유로 선형 가속도를 제공할 수 없는 구현에서 최선의 지원을 제공하기 위한 수단으로 제공됩니다.

참고: 실제로 중력을 포함한 가속도Motion Sensors Explainer § accelerometer 또는 [G-FORCE]에서 가져온 원시 측정값을 나타냅니다. 반면 선형 가속도Motion Sensors Explainer § linear-acceleration-sensor의 측정값을 제공하며, 센서 융합 결과일 가능성이 높습니다. [MOTION-SENSORS][ACCELEROMETER]에는 다양한 가속도계 및 측정할 수 있는 가속도 유형에 대한 보다 상세한 논의가 있습니다.

회전 속도디바이스 좌표계에서 지정된 축을 기준으로 디바이스가 회전하는 속도를 측정합니다. 디바이스 방향과 마찬가지로 회전은 오른손 규칙을 따라야 하며, 축의 양의 방향에서 볼 때 시계 방향이 양수입니다. 회전 속도는 초당 도(deg/s) 단위로 측정됩니다.

참고: [MOTION-SENSORS][GYROSCOPE]에는 자이로스코프, 회전 속도 및 측정에 대한 보다 상세한 논의가 포함되어 있습니다.

4. 권한

이 통합은 위험 요소입니다. DeviceMotionEvent.requestPermission()DeviceOrientationEvent.requestPermission() 테스트의 낮은 통과율 때문입니다.

이 명세는 강력한 기능이며, 다음과 같은 권한을 정의합니다. 이 권한들은 다음 정책 제어 기능이며, 아래와 같은 기본 허용 목록을 가집니다:

참고: 어떤 이벤트가 디스패치되는지는 어떤 권한허가되었는지에 따라 달라집니다:

5. 작업 소스

작업 소스는 이 명세에서 언급된 작업에 대해 디바이스 움직임 및 방향 작업 소스입니다.

6. API

6.1. deviceorientation 이벤트

partial interface Window {
    [SecureContext] attribute EventHandler ondeviceorientation;
};

[Exposed=Window, SecureContext]
interface DeviceOrientationEvent : Event {
    constructor(DOMString type, optional DeviceOrientationEventInit eventInitDict = {});
    readonly attribute double? alpha;
    readonly attribute double? beta;
    readonly attribute double? gamma;
    readonly attribute boolean absolute;

    static Promise<PermissionState> requestPermission(optional boolean absolute = false);
};

dictionary DeviceOrientationEventInit : EventInit {
    double? alpha = null;
    double? beta = null;
    double? gamma = null;
    boolean absolute = false;
};

ondeviceorientation 속성은 이벤트 핸들러 IDL 속성이며, ondeviceorientation 이벤트 핸들러입니다. 이벤트 핸들러 이벤트 타입deviceorientation 입니다.

alpha 속성은 초기화된 값을 반환해야 합니다. 이 값은 § 3.1 디바이스 방향에서 설명된 Z - X' - Y'' 내적 테이트-브라이언 각에서 Z축을 기준으로 한 회전을 나타냅니다.

beta 속성은 초기화된 값을 반환해야 합니다. 이 값은 § 3.1 디바이스 방향에서 설명된 Z축 회전 후 생성된 X'축을 기준으로 한 회전을 나타냅니다.

gamma 속성은 초기화된 값을 반환해야 합니다. 이 값은 § 3.1 디바이스 방향에서 설명된 Z축과 X'축 회전이 적용된 후 Y''축을 기준으로 한 회전을 나타냅니다.

absolute 속성은 초기화된 값을 반환해야 합니다. 이 값은 상대 방향 또는 절대 방향 데이터가 제공되고 있는지 여부를 나타냅니다.

requestPermission(absolute) 메소드 단계:
  1. global현재 글로벌 객체로 설정합니다.

  2. hasTransientActivationthis관련 글로벌 객체일시적 활성화가 있으면 true, 그렇지 않으면 false로 설정합니다.

  3. promise새로운 promisethis관련 Realm에서 생성합니다.

  4. permissions를 « "accelerometer", "gyroscope" »로 설정합니다.

  5. absolute가 true이면 append "magnetometer" »를 permissions에 추가합니다.

  6. 다음 단계들을 병렬로 실행합니다:

    1. name에 대해 permissions에서:

      1. name권한 상태가 "prompt"이고 hasTransientActivation이 false인 경우:

        1. 글로벌 작업을 큐에 추가하여 디바이스 움직임 및 방향 작업 소스에서 globalpromise를 reject합니다. "NotAllowedError" DOMException으로.

        2. 반환합니다.

    2. permissionState를 "granted"로 설정합니다.

    3. name에 대해 permissions에서:

      참고: 여러 권한을 한 번에 요청하는 알고리즘은 없습니다. 하지만, 사용자 에이전트는 여러 종류의 미디어에 대한 동시 요청을 하나의 사용자 프롬프트로 묶는 것을 권장합니다.

      1. 사용 권한 요청 결과가 "granted"가 아니면:

        1. permissionState를 "denied"로 설정합니다.

        2. 반복 중단.

    4. 글로벌 작업을 큐에 추가하여 디바이스 움직임 및 방향 작업 소스에서 globalpromise를 resolve합니다. permissionState로.

  7. promise를 반환합니다.

방향 이벤트를 발화한다는 것은 DOMString event, Window window, boolean absolute를 받아 다음과 같이 한다:
  1. orientation을 null로 설정한다.

  2. topLevelTraversablewindownavigable최상위 traversable로 설정한다.

  3. virtualSensorType을 "relative-orientation" ( absolute가 false일 때 ) 또는 "absolute-orientation" (그 외)로 설정한다.

  4. topLevelTraversablevirtual sensor mappingvirtualSensorType을 포함한다면:

    1. virtualSensortopLevelTraversablevirtual sensor mapping[virtualSensorType]으로 설정한다.

    2. virtualSensor측정값 제공 가능 플래그가 true라면:

      1. orientationvirtualSensor에 제공된 최신 "alpha", "beta", "gamma" 키의 측정값으로 설정한다.

  5. 그렇지 않은 경우:

    1. absolute가 false이면:

      1. orientation을 디바이스의 상대 방향으로 3차원 평면에서 설정한다.

    2. 그 외:

      1. orientation을 디바이스의 절대 방향으로 3차원 평면에서 설정한다.

  6. permissions을 null로 설정한다.

  7. absolute가 false이면:

    1. permissions을 « "accelerometer", "gyroscope" »로 설정한다.

  8. 그 외:

    1. permissions을 « "accelerometer", "gyroscope", "magnetometer" »로 설정한다.

  9. environmentwindow관련 설정 객체로 설정한다.

  10. 다음 단계들을 병렬로 실행한다:

    1. permission에 대해 permissions에서:

      1. state현재 권한 상태 획득 결과로 permissionenvironment를 이용하여 설정한다.

      2. state가 "granted"가 아니면, 반환한다.

    2. 글로벌 작업을 큐에 추가하여 디바이스 움직임 및 방향 작업 소스에서 window로 다음 단계를 실행한다:

      1. zorientation의 Z - X' - Y'' 내적 테이트-브라이언 각에서 Z축 표현값(또는 각 값 제공 불가 시 null)으로 설정한다.

      2. z가 null이 아니면, z의 정밀도를 0.1도로 제한한다.

      3. xorientation의 Z - X' - Y'' 내적 테이트-브라이언 각에서 X'축 표현값(또는 각 값 제공 불가 시 null)으로 설정한다.

      4. x가 null이 아니면, x의 정밀도를 0.1도로 제한한다.

      5. yorientation의 Z - X' - Y'' 내적 테이트-브라이언 각에서 Y''축 표현값(또는 각 값 제공 불가 시 null)으로 설정한다.

      6. y가 null이 아니면, y의 정밀도를 0.1도로 제한한다.

      7. 이벤트 발화event 이름으로 window에서, DeviceOrientationEvent를 사용하여, alpha 속성은 z으로, beta 속성은 x으로, gamma 속성은 y으로, absolute 속성은 absolute로 초기화하여 발화한다.

중대한 방향 변화란 이전 값과 비교해 방향 값이 달라졌을 때 deviceorientation 또는 deviceorientationabsolute 이벤트를 발화할 만한 차이가 있는 경우를 의미합니다. 중대한 방향 변화 판단 방법은 구현 정의이며, 최대 1도 변화에 대한 임계값을 권장합니다. 또한 충분히 최신 데이터가 아니라고 판단될 경우에도 이벤트가 발화될 수 있습니다.

참고: 구현체는 § 9 자동화를 고려하여 중대한 방향 변화가 발생했는지 판단해야 하며, 가상 센서 판독값 업데이트가 그 판단에 영향을 줄 수 있습니다.

중대한 방향 변화가 발생할 때마다, 사용자 에이전트는 navigable활성 window window에서 다음 단계를 실행해야 합니다:
  1. documentwindow관련 문서로 설정합니다.

  2. documentvisibility state"visible"이 아니면, 반환합니다.

  3. absolute를 false로 설정합니다.

  4. features를 « "accelerometer", "gyroscope" »로 설정합니다.

  5. 구현이 상대 방향을 제공할 수 없거나, 결과로 얻어진 절대 방향 데이터가 더 정확한 경우:

    1. absolute를 true로 설정합니다.

    2. features에 "magnetometer"를 추가합니다.

  6. feature에 대해 features에서:

    1. document해당 feature 사용 허가가 없으면, 반환합니다.

  7. 방향 이벤트 발화deviceorientation, window, absolute로 실행합니다.

구현이 방향 정보를 영원히 제공할 수 없는 경우, 이벤트는 alpha, betagamma 속성을 null로, absolute 속성을 false로 설정하여 발화되어야 합니다.

6.2. deviceorientationabsolute 이벤트

deviceorientationabsolute 이벤트 및 ondeviceorientationabsolute 이벤트 핸들러 IDL 속성은 위험 요소입니다. 제한적인 구현 경험 때문입니다.
partial interface Window {
    [SecureContext] attribute EventHandler ondeviceorientationabsolute;
};

ondeviceorientationabsolute 속성은 이벤트 핸들러 IDL 속성이며, ondeviceorientationabsolute 이벤트 핸들러입니다. 이벤트 핸들러 이벤트 타입deviceorientationabsolute 입니다.

deviceorientationabsolute 이벤트는 deviceorientation 이벤트와 완전히 유사하지만, 반드시 절대 방향 데이터만을 제공해야 한다는 점이 다릅니다.

중대한 방향 변화가 발생할 때마다, 사용자 에이전트는 navigable활성 window window에서 다음 단계를 실행해야 한다:
  1. 방향 이벤트 발화deviceorientationabsolute, window, true로 실행한다.

구현이 절대 방향 정보를 영원히 제공할 수 없는 경우, 이벤트는 alpha, betagamma 속성을 null로, absolute 속성을 true로 설정하여 발화되어야 한다.

6.3. devicemotion 이벤트

6.3.1. DeviceMotionEventAcceleration 인터페이스

[Exposed=Window, SecureContext]
interface DeviceMotionEventAcceleration {
    readonly attribute double? x;
    readonly attribute double? y;
    readonly attribute double? z;
};

DeviceMotionEventAcceleration 인터페이스는 § 3.2 디바이스 움직임에서 설명된 디바이스의 가속도를 나타냅니다. 다음과 같은 관련 데이터를 가집니다:

x축 가속도

디바이스의 X축을 따라 가속되는 속도, 또는 null. 초기값은 null입니다.

y축 가속도

디바이스의 Y축을 따라 가속되는 속도, 또는 null. 초기값은 null입니다.

z축 가속도

디바이스의 Z축을 따라 가속되는 속도, 또는 null. 초기값은 null입니다.

x getter 단계는 thisx축 가속도 값을 반환한다.

y getter 단계는 thisy축 가속도 값을 반환한다.

z getter 단계는 thisz축 가속도 값을 반환한다.

6.3.2. DeviceMotionEventRotationRate 인터페이스

[Exposed=Window, SecureContext]
interface DeviceMotionEventRotationRate {
    readonly attribute double? alpha;
    readonly attribute double? beta;
    readonly attribute double? gamma;
};

DeviceMotionEventRotationRate 인터페이스는 회전 속도§ 3.2 디바이스 움직임에서 설명한 대로 나타냅니다. 다음과 같은 관련 데이터를 가집니다:

x축 회전 속도

디바이스의 X축을 기준으로 한 회전 속도, 또는 null. 초기값은 null입니다.

y축 회전 속도

디바이스의 Y축을 기준으로 한 회전 속도, 또는 null. 초기값은 null입니다.

z축 회전 속도

디바이스의 Z축을 기준으로 한 회전 속도, 또는 null. 초기값은 null입니다.

alpha getter 단계는 thisx축 회전 속도 값을 반환한다.

beta getter 단계는 thisy축 회전 속도 값을 반환한다.

gamma getter 단계는 thisz축 회전 속도 값을 반환한다.

6.3.3. DeviceMotionEvent 인터페이스

partial interface Window {
    [SecureContext] attribute EventHandler ondevicemotion;
};

[Exposed=Window, SecureContext]
interface DeviceMotionEvent : Event {
    constructor(DOMString type, optional DeviceMotionEventInit eventInitDict = {});
    readonly attribute DeviceMotionEventAcceleration? acceleration;
    readonly attribute DeviceMotionEventAcceleration? accelerationIncludingGravity;
    readonly attribute DeviceMotionEventRotationRate? rotationRate;
    readonly attribute double interval;

    static Promise<PermissionState> requestPermission();
};

dictionary DeviceMotionEventAccelerationInit {
    double? x = null;
    double? y = null;
    double? z = null;
};

dictionary DeviceMotionEventRotationRateInit {
    double? alpha = null;
    double? beta = null;
    double? gamma = null;
};

dictionary DeviceMotionEventInit : EventInit {
    DeviceMotionEventAccelerationInit acceleration;
    DeviceMotionEventAccelerationInit accelerationIncludingGravity;
    DeviceMotionEventRotationRateInit rotationRate;
    double interval = 0;
};

ondevicemotion 속성은 이벤트 핸들러 IDL 속성이며, ondevicemotion 이벤트 핸들러입니다. 이벤트 핸들러 이벤트 타입devicemotion 입니다.

acceleration 속성은 초기화된 값을 반환해야 합니다. 객체가 생성될 때 이 속성은 null로 초기화되어야 합니다. 디바이스의 선형 가속도를 나타냅니다.

accelerationIncludingGravity 속성은 초기화된 값을 반환해야 합니다. 객체가 생성될 때 이 속성은 null로 초기화되어야 합니다. 디바이스의 중력을 포함한 가속도를 나타냅니다.

rotationRate 속성은 초기화된 값을 반환해야 합니다. 객체가 생성될 때 이 속성은 null로 초기화되어야 합니다. 디바이스의 회전 속도를 나타냅니다.

interval 속성은 초기화된 값을 반환해야 합니다. 이 값은 하드웨어로부터 데이터를 얻어오는 간격을 나타내며 밀리초(ms) 단위로 표현되어야 합니다. 웹 애플리케이션에서 데이터를 쉽게 필터링할 수 있도록 일정하게 유지됩니다.

requestPermission() 메소드 단계는 다음과 같습니다:
  1. global현재 글로벌 객체로 설정합니다.

  2. hasTransientActivationthis관련 글로벌 객체일시적 활성화가 있으면 true, 그렇지 않으면 false로 설정합니다.

  3. result새로운 promisethis관련 Realm에서 생성합니다.

  4. 다음 단계들을 병렬로 실행합니다:

    1. permissions를 « "accelerometer", "gyroscope" »로 설정합니다.

    2. name에 대해 permissions에서:

      1. name권한 상태가 "prompt"이고 hasTransientActivation이 false인 경우:

        1. 글로벌 작업을 큐에 추가하여 디바이스 움직임 및 방향 작업 소스에서 globalresult를 reject합니다. "NotAllowedError" DOMException으로.

        2. 반환합니다.

    3. permissionState를 "granted"로 설정합니다.

    4. name에 대해 permissions에서:

      참고: 여러 권한을 한 번에 요청하는 알고리즘은 없습니다. 하지만, 사용자 에이전트는 여러 종류의 미디어에 대한 동시 요청을 하나의 사용자 프롬프트로 묶는 것을 권장합니다.

      1. 사용 권한 요청 결과가 "granted"가 아니면:

        1. permissionState를 "denied"로 설정합니다.

        2. 반복 중단.

    5. 글로벌 작업을 큐에 추가하여 디바이스 움직임 및 방향 작업 소스에서 globalresult를 resolve합니다. permissionState로.

  5. result를 반환합니다.

구현 정의된 간격 interval마다, 사용자 에이전트는 navigable활성 window window에서 다음 단계를 실행해야 합니다:
  1. documentwindow관련 문서로 설정합니다.

  2. documentvisibility state가 "visible"이 아니면, 반환합니다.

  3. policy에 대해 « "accelerometer", "gyroscope" »에서:

    1. document해당 기능 사용 허가가 없으면 정책 제어 기능 policy에 대해 반환한다.

  4. topLevelTraversablewindownavigable최상위 traversable로 설정합니다.

  5. platformLinearAcceleration을 null로 설정합니다.

  6. topLevelTraversablevirtual sensor mapping"linear-acceleration"을 포함하는 경우:

    1. virtualSensortopLevelTraversablevirtual sensor mapping["linear-acceleration"]으로 설정합니다.

    2. virtualSensor측정값 제공 가능 플래그가 true이면, platformLinearAccelerationvirtualSensor에 제공된 최신 측정값으로 설정합니다.

  7. 그 외에 구현이 선형 가속도를 제공할 수 있으면:

    1. platformLinearAcceleration을 디바이스의 선형 가속도 (X, Y, Z축)로 설정합니다.

  8. acceleration을 null로 설정합니다.

  9. platformLinearAcceleration이 null이 아니면:

    1. acceleration새로운 DeviceMotionEventAcceleration으로 windowrealm에서 생성합니다.

    2. accelerationx축 가속도platformLinearAcceleration의 X축 값(불가하면 null)으로 설정합니다.

    3. accelerationx축 가속도가 null이 아니면, 정밀도를 0.1 m/s2 이하로 제한합니다.

    4. accelerationy축 가속도platformLinearAcceleration의 Y축 값(불가하면 null)으로 설정합니다.

    5. accelerationy축 가속도가 null이 아니면, 정밀도를 0.1 m/s2 이하로 제한합니다.

    6. accelerationz축 가속도platformLinearAcceleration의 Z축 값(불가하면 null)으로 설정합니다.

    7. accelerationz축 가속도가 null이 아니면, 정밀도를 0.1 m/s2 이하로 제한합니다.

  10. platformAccelerationIncludingGravity를 null로 설정합니다.

  11. topLevelTraversablevirtual sensor mapping"accelerometer"를 포함하는 경우:

    1. virtualSensortopLevelTraversablevirtual sensor mapping["accelerometer"]로 설정합니다.

    2. virtualSensor측정값 제공 가능 플래그가 true이면, platformAccelerationIncludingGravityvirtualSensor에 제공된 최신 측정값으로 설정합니다.

  12. 그 외에 구현이 중력을 포함한 가속도를 제공할 수 있으면:

    1. platformAccelerationIncludingGravity를 디바이스의 선형 가속도 (X, Y, Z축)로 설정합니다.

  13. accelerationIncludingGravity를 null로 설정합니다.

  14. platformAccelerationIncludingGravity가 null이 아니면:

    1. accelerationIncludingGravity새로운 DeviceMotionEventAcceleration으로 windowrealm에서 생성합니다.

    2. accelerationIncludingGravityx축 가속도platformAccelerationIncludingGravity의 X축 값(불가하면 null)으로 설정합니다.

    3. accelerationIncludingGravityx축 가속도가 null이 아니면, 정밀도를 0.1 m/s2 이하로 제한합니다.

    4. accelerationIncludingGravityy축 가속도platformAccelerationIncludingGravity의 Y축 값(불가하면 null)으로 설정합니다.

    5. accelerationIncludingGravityy축 가속도가 null이 아니면, 정밀도를 0.1 m/s2 이하로 제한합니다.

    6. accelerationIncludingGravityz축 가속도platformAccelerationIncludingGravity의 Z축 값(불가하면 null)으로 설정합니다.

    7. accelerationIncludingGravityz축 가속도가 null이 아니면, 정밀도를 0.1 m/s2 이하로 제한합니다.

  15. platformRotationRate를 null로 설정합니다.

  16. topLevelTraversablevirtual sensor mapping"gyroscope"를 포함하는 경우:

    1. virtualSensortopLevelTraversablevirtual sensor mapping["gyroscope"]로 설정합니다.

    2. virtualSensor측정값 제공 가능 플래그가 true이면, platformRotationRatevirtualSensor에 제공된 최신 측정값으로 설정합니다.

  17. 그 외에 구현이 회전 속도를 제공할 수 있으면:

    1. platformRotationRate를 디바이스의 회전 속도 (X, Y, Z축)로 설정합니다.

  18. rotationRate를 null로 설정합니다.

  19. platformRotationRate가 null이 아니면:

    1. rotationRate새로운 DeviceMotionEventRotationRate으로 windowrealm에서 생성합니다.

    2. rotationRatex축 회전 속도platformRotationRate의 X축 값(불가하면 null)으로 설정합니다.

    3. rotationRatex축 회전 속도가 null이 아니면, 정밀도를 0.1 deg/s 이하로 제한합니다.

    4. rotationRatey축 회전 속도platformRotationRate의 Y축 값(불가하면 null)으로 설정합니다.

    5. rotationRatey축 회전 속도가 null이 아니면, 정밀도를 0.1 deg/s 이하로 제한합니다.

    6. rotationRatez축 회전 속도platformRotationRate의 Z축 값(불가하면 null)으로 설정합니다.

    7. rotationRatez축 회전 속도가 null이 아니면, 정밀도를 0.1 deg/s 이하로 제한합니다.

  20. environmentwindow관련 설정 객체로 설정합니다.

  21. 다음 단계들을 병렬로 실행한다:

    1. permission에 대해 « "accelerometer", "gyroscope" »:

      1. state현재 권한 상태 획득 결과로 permissionenvironment를 이용해 설정한다.

      2. state가 "granted"이 아니면, 반환한다.

    2. 글로벌 작업을 큐에 추가하여 디바이스 움직임 및 방향 작업 소스에서 window로 다음 단계들을 실행한다:

      1. 이벤트 발화를 "devicemotion" 이름으로 window에, DeviceMotionEvent를 사용하여, acceleration 속성은 acceleration으로, accelerationIncludingGravity 속성은 accelerationIncludingGravity로, rotationRate 속성은 rotationRate로, interval 속성은 interval로 초기화하여 발화한다.

구현이 움직임 정보를 영원히 제공할 수 없는 경우, 이벤트는 acceleration, accelerationIncludingGravityrotationRate 속성을 null로 설정하여 발화되어야 한다.

7. 보안 및 개인정보 보호 고려사항

이 명세에서 정의하는 API는 가속도계, 자이로스코프, 자기장계 등 하드웨어 센서로부터 정보를 얻는 데 사용할 수 있습니다. 제공되는 데이터는 민감할 수 있으며, 악의적인 웹 페이지로부터 공격의 대상이 될 수 있습니다. 가속도계, 자이로스코프, 자기장계의 보정 값은 특정 센서 하드웨어에 대한 영속적인 정보를 드러낼 수 있습니다 [SENSORID]. 주요 공격 벡터는 다음과 같이 분류할 수 있습니다:

이를 고려하여, 구현체는 웹 페이지에서 센서를 사용하는 경우 시각적 표시를 고려할 수 있습니다. 또한, 이 명세는 requestPermission() API 호출을 통해 사용자 에이전트가 디바이스 움직임 및/또는 방향 데이터를 제공하기 전에 반드시 사용자의 명시적 동의를 받아야 함을 요구합니다.

더불어, 개인정보 위험과 지문 채취 및 기타 공격 가능성을 최소화하기 위해, 구현체는 다음을 반드시 따라야 합니다:

이러한 항목을 구현하면 모바일 디바이스의 배터리 수명에도 긍정적인 영향을 줄 수 있습니다.

최대 샘플링 빈도 제한에 대한 추가 구현 경험을 수집하고 있습니다.

8. 접근성 고려사항

DeviceOrientation 이벤트는 새로운 입력 방식을 제공하여 사용자의 참신한 상호작용을 가능하게 합니다. 더 많은 사람들이 여러분이 만드는 경험에 접근할 수 있도록 하기 위해 다음 사항을 고려해 주세요:

다음과 같은 두 가지 사용자 요구가 발생할 수 있으며, 이는 보통 사용자 에이전트나 운영체제가 관리하게 됩니다. 하지만, 이러한 사항을 염두에 두는 것은 여러분의 콘텐츠나 앱이 어떻게 사용될 수 있는지 이해하는 데 도움이 됩니다.

9. 자동화

이 기능은 위험 요소입니다. 구현 경험이 제한적이기 때문입니다.

이 명세는 테스트 작성자에게 도전이 될 수 있는데, 여기서 정의된 이벤트는 물리적 하드웨어의 판독값에 따라 달라지며 쉽게 제어할 수 없기 때문입니다.

이 문제를 해결하기 위해, 본 문서는 [WEBDRIVER2]확장 명령과, Generic Sensor API § 9 자동화에서 제시된 인프라를 기반으로 합니다. 별도의 독립적인 인프라와 확장 명령을 새로 개발하는 옵션보다 이를 선택한 이유는 두 명세 간에 상당한 중복이 있기 때문입니다. [GENERIC-SENSOR] 명세의 테스트 역시 유사한 과제를 가지고 있고, 많은 파생 API(예: [GYROSCOPE])도 유사한 정보를 얻고 제공합니다.

이 명세는 Generic Sensor API § 9 자동화 섹션만을 지원하도록 구현을 요구하며, 해당 명세의 인터페이스와 이벤트는 요구하지 않습니다.

9.1. 디바이스 방향 자동화

deviceorientation 이벤트의 자동화 지원은 가상 센서(가속도계, 자이로스코프, 필요 시 자기장계) 기반으로 구축됩니다.

플랫폼에서 사용자 에이전트가 얻는 방향 데이터는 가속도계, 자이로스코프, 필요 시 자기장계에서 가져옵니다. 그러나 움직임 데이터와 달리, 이 저수준 판독값은 § 3.1 디바이스 방향에서 설명한 형태의 오일러 각으로 변환되어야 합니다. 게다가, 플랫폼이 원시 가속도와 회전 데이터를 이미 변환해주는 추가 API를 사용자 에이전트에게 제공할 수도 있습니다.

따라서, 구현체(및 자동화 사용자)가 각기 다른 측정 단위를 사용하는 저수준 가상 센서를 통해 방향 판독값을 제공하도록 요구하는 대신, 이 명세는 상대 및 절대 방향 데이터를 명세에서 사용하는 형식으로 제공하는 추가 가상 센서 타입을 정의합니다.

9.1.1. 방향 데이터 판독값 파싱 알고리즘

방향 데이터 판독값 파싱 알고리즘을 JSON Object parameters에 대해 수행하려면:
  1. alphaget a propertyparameters에서 "alpha"를 가져온 결과로 설정한다.

  2. alphaNumber가 아니거나, 값이 NaN, +∞, −∞이면 undefined를 반환한다.

  3. alpha가 [0, 360) 범위가 아니면 undefined를 반환한다.

  4. betaget a propertyparameters에서 "beta"를 가져온 결과로 설정한다.

  5. betaNumber가 아니거나, 값이 NaN, +∞, −∞이면 undefined를 반환한다.

  6. beta가 [-180, 180) 범위가 아니면 undefined를 반환한다.

  7. gammaget a propertyparameters에서 "gamma"를 가져온 결과로 설정한다.

  8. gammaNumber가 아니거나, 값이 NaN, +∞, −∞이면 undefined를 반환한다.

  9. gamma가 [-90, 90) 범위가 아니면 undefined를 반환한다.

  10. «[ "alpha" → alpha, "beta" → beta, "gamma" → gamma ]»로 된 새 ordered map을 반환한다.

참고: 반환 값은 ordered map으로, 센서 판독 개념에 대한 의존성을 피하기 위함입니다. 위 알고리즘 목적상 두 개념은 서로 대체 가능합니다.

9.1.2. "absolute-orientation" 가상 센서 타입

타입별 가상 센서 메타데이터 map 은 다음 항목을 가져야 합니다:

"absolute-orientation"

가상 센서 메타데이터로서, 판독값 파싱 알고리즘방향 데이터 판독값 파싱이다.

9.1.3. "relative-orientation" 가상 센서 타입

타입별 가상 센서 메타데이터 map 은 다음 항목을 가져야 합니다:

"relative-orientation"

가상 센서 메타데이터로서, 판독값 파싱 알고리즘방향 데이터 판독값 파싱이다.

9.2. 디바이스 움직임 자동화

사용자 에이전트가 플랫폼에서 얻는 움직임 데이터는 가속도계와 자이로스코프에서 가져옵니다. 이 명세는 타입별 가상 센서 메타데이터 항목을 정의하며, 이는 [ACCELEROMETER][GYROSCOPE] 명세와 공유됩니다.

가속도계 가상 센서는 플랫폼에 중력을 포함한 가속도 데이터를 제공합니다. 선형 가속도 가상 센서는 플랫폼에 선형 가속도 데이터를 제공합니다. 자이로스코프 가상 센서는 플랫폼에 회전 속도 데이터를 제공합니다.

9.2.1. "accelerometer" 가상 센서 타입

타입별 가상 센서 메타데이터 map 은 다음 항목을 가져야 합니다:

"accelerometer"

가상 센서 메타데이터로서, 판독값 파싱 알고리즘parse xyz reading이다.

9.2.2. "linear-acceleration" 가상 센서 타입

타입별 가상 센서 메타데이터 map 은 다음 항목을 가져야 합니다:

"linear-acceleration"

가상 센서 메타데이터로서, 판독값 파싱 알고리즘parse xyz reading이다.

9.2.3. "gyroscope" 가상 센서 타입

타입별 가상 센서 메타데이터 map 은 다음 항목을 가져야 합니다:

"gyroscope"

가상 센서 메타데이터로서, 판독값 파싱 알고리즘parse xyz reading이다.

A 예제

이 섹션은 규범적이지 않습니다.

A.1 나침반 방위 계산

이 섹션은 규범적이지 않습니다.

다음 예제는 DeviceOrientation 이벤트 사용자에게 도움을 주기 위한 것입니다.

소개 섹션에서는 DeviceOrientation 이벤트를 사용하여 화면이 수평일 때 나침반 방위를 얻는 예제를 제공했습니다. 이 예제에서는 사용자가 화면을 대략적으로 수직으로 자신 앞에 들고 있을 때 사용자가 바라보는 나침반 방위를 결정하는 방법을 보여줍니다. 증강현실 시스템이 그 활용 예입니다.

좀 더 정확히는, 디바이스 화면에 수직이며 화면 뒤쪽을 향하는 벡터의 수평 성분의 나침반 방위를 구하려는 것입니다.

v가 회전된 디바이스 바디 프레임 xyz에서 이 벡터를 나타낸다면 v는 다음과 같습니다.

v = [0; 0; -1]

z축 회전에 의해 v가 변환되는 것은 다음 회전 행렬로 나타낼 수 있습니다.

Z = [cos(alpha) -sin(alpha) 0; sin(alpha) cos(alpha) 0; 0 0 1]

x축 회전에 의해 v가 변환되는 것은 다음 회전 행렬로 나타낼 수 있습니다.

X = [1 0 0; 0 cos(beta) -sin(beta); 0 sin(beta) cos(beta)]

y축 회전에 의해 v가 변환되는 것은 다음 회전 행렬로 나타낼 수 있습니다.

Y = [cos(gamma) 0 sin(gamma); 0 1 0; -sin(gamma) 0 cos(gamma)]

R이 지구 프레임 XYZ에서 디바이스의 전체 회전 행렬을 나타낸다면, 초기 바디 프레임이 지구와 정렬되어 있으므로 R은 다음과 같습니다.

R = ZXY = [[cos(alpha) cos(gamma)-sin(alpha) sin(beta) sin(gamma), -cos(beta) sin(alpha), cos(gamma) sin(alpha) sin(beta)+cos(alpha) sin(gamma)], [cos(gamma) sin(alpha)+cos(alpha) sin(beta) sin(gamma), cos(alpha) cos(beta), sin(alpha) sin(gamma)-cos(alpha) cos(gamma) sin(beta)], [-cos(beta) sin(gamma), sin(beta), cos(beta) cos(gamma)]]

v'가 지구 프레임 XYZ에서 v를 나타낸다면, 초기 바디 프레임이 지구와 정렬되어 있으므로 v'는 다음과 같습니다.

v' = Rv v' = [-cos(alpha)sin(gamma)-sin(alpha)sin(beta)cos(gamma); -sin(alpha)sin(gamma)+cos(alpha)sin(beta)cos(gamma); -cos(beta)cos(gamma)]

나침반 방위 θ는 다음과 같이 주어집니다.

theta = atan((v'_x)/(v'_y)) = atan((-cos(alpha)sin(gamma)-sin(alpha)sin(beta)cos(gamma))/(-sin(alpha)sin(gamma)+cos(alpha)sin(beta)cos(gamma)))

단, β와 γ가 모두 0이 아니어야 합니다.

위 나침반 방위 계산은 아래 자바스크립트 코드로 표현할 수 있으며, 전달된 파라미터가 정의되어 있고 null이 아니며 absolute 값일 때 올바른 나침반 방위를 반환합니다.

var degtorad = Math.PI / 180; // Degree-to-Radian conversion

function compassHeading( alpha, beta, gamma ) {

  var _x = beta  ? beta  * degtorad : 0; // beta value
  var _y = gamma ? gamma * degtorad : 0; // gamma value
  var _z = alpha ? alpha * degtorad : 0; // alpha value

  var cX = Math.cos( _x );
  var cY = Math.cos( _y );
  var cZ = Math.cos( _z );
  var sX = Math.sin( _x );
  var sY = Math.sin( _y );
  var sZ = Math.sin( _z );

  // Calculate Vx and Vy components
  var Vx = - cZ * sY - sZ * sX * cY;
  var Vy = - sZ * sY + cZ * sX * cY;

  // Calculate compass heading
  var compassHeading = Math.atan( Vx / Vy );

  // Convert compass heading to use whole unit circle
  if( Vy < 0 ) {
    compassHeading += Math.PI;
  } else if( Vx < 0 ) {
    compassHeading += 2 * Math.PI;
  }

  return compassHeading * ( 180 / Math.PI ); // Compass Heading (in degrees)

}

일관성 확인을 위해 γ = 0으로 설정하면,

theta = atan(-sin(alpha)sin(beta)/cos(alpha)sin(beta)) = -alpha

예상대로입니다.

또는 β = 90으로 설정하면,

theta = atan((-cos(alpha)sin(gamma)-sin(alpha)cos(gamma))/(-sin(alpha)sin(gamma)+cos(alpha)cos(gamma))) theta = atan(-sin(alpha+gamma)/cos(alpha+gamma)) = -(alpha+gamma)

예상대로입니다.

A.2 대체 디바이스 방향 표현

이 섹션은 규범적이지 않습니다.

Tait-Bryan 각을 이용한 방향 기술은 짐벌락 [GIMBALLOCK]과 같은 단점이 있을 수 있습니다. 의도된 응용에 따라 Device Orientation 값을 다른 회전 표현으로 변환하는 것이 유용할 수 있습니다.

첫 번째 대체 방향 표현은 회전 행렬을 사용합니다. 위 작동 예제에 제공된 구성 요소 회전 행렬을 결합하여 디바이스 바디 프레임의 방향을 하나의 회전 행렬로 나타낼 수 있습니다.

R이 지구 프레임 XYZ에서 디바이스의 회전 행렬을 나타낸다면, 초기 바디 프레임이 지구와 정렬되어 있으므로 R은 다음과 같습니다.

R = ZXY = [[cos(alpha) cos(gamma)-sin(alpha) sin(beta) sin(gamma), -cos(beta) sin(alpha), cos(gamma) sin(alpha) sin(beta)+cos(alpha) sin(gamma)], [cos(gamma) sin(alpha)+cos(alpha) sin(beta) sin(gamma), cos(alpha) cos(beta), sin(alpha) sin(gamma)-cos(alpha) cos(gamma) sin(beta)], [-cos(beta) sin(gamma), sin(beta), cos(beta) cos(gamma)]]
위에서 결합된 회전 행렬은 전달된 파라미터가 정의되어 있고 null이 아니며 absolute 값일 때 아래와 같이 자바스크립트로 표현할 수 있습니다.
var degtorad = Math.PI / 180; // Degree-to-Radian conversion

function getRotationMatrix( alpha, beta, gamma ) {

  var _x = beta  ? beta  * degtorad : 0; // beta value
  var _y = gamma ? gamma * degtorad : 0; // gamma value
  var _z = alpha ? alpha * degtorad : 0; // alpha value

  var cX = Math.cos( _x );
  var cY = Math.cos( _y );
  var cZ = Math.cos( _z );
  var sX = Math.sin( _x );
  var sY = Math.sin( _y );
  var sZ = Math.sin( _z );

  //
  // ZXY rotation matrix construction.
  //

  var m11 = cZ * cY - sZ * sX * sY;
  var m12 = - cX * sZ;
  var m13 = cY * sZ * sX + cZ * sY;

  var m21 = cY * sZ + cZ * sX * sY;
  var m22 = cZ * cX;
  var m23 = sZ * sY - cZ * cY * sX;

  var m31 = - cX * sY;
  var m32 = sX;
  var m33 = cX * cY;

  return [
    m11,    m12,    m13,
    m21,    m22,    m23,
    m31,    m32,    m33
  ];

};

또 다른 대체 디바이스 방향 데이터 표현은 쿼터니언(Quaternion)입니다. [QUATERNIONS]

q가 지구 프레임 XYZ에서 디바이스의 단위 쿼터니언을 나타낸다면, 초기 바디 프레임이 지구와 정렬되어 있으므로 q는 다음과 같습니다.

q = [[q_w], [q_x], [q_y], [q_z]] = [[cos(beta)cos(gamma)cos(alpha) - sin(beta)sin(gamma)sin(alpha)], [sin(beta)cos(gamma)cos(alpha) - cos(beta)sin(gamma)sin(alpha)], [cos(beta)sin(gamma)cos(alpha) + sin(beta)cos(gamma)sin(alpha)], [cos(beta)cos(gamma)sin(alpha) + sin(beta)sin(gamma)cos(alpha)]]
위 쿼터니언은 전달된 파라미터가 정의되어 있고 absolute 값이며 null이 아니면 아래와 같이 자바스크립트로 표현할 수 있습니다.
var degtorad = Math.PI / 180; // Degree-to-Radian conversion

function getQuaternion( alpha, beta, gamma ) {

  var _x = beta  ? beta  * degtorad : 0; // beta value
  var _y = gamma ? gamma * degtorad : 0; // gamma value
  var _z = alpha ? alpha * degtorad : 0; // alpha value

  var cX = Math.cos( _x/2 );
  var cY = Math.cos( _y/2 );
  var cZ = Math.cos( _z/2 );
  var sX = Math.sin( _x/2 );
  var sY = Math.sin( _y/2 );
  var sZ = Math.sin( _z/2 );

  //
  // ZXY quaternion construction.
  //

  var w = cX * cY * cZ - sX * sY * sZ;
  var x = sX * cY * cZ - cX * sY * sZ;
  var y = cX * sY * cZ + sX * cY * sZ;
  var z = cX * cY * sZ + sX * sY * cZ;

  return [ w, x, y, z ];

}

단위 쿼터니언이 올바르게 생성되었는지 Lagrange의 네 제곱수 정리를 이용해 확인할 수 있습니다.

q_w^2 * q_x^2 * q_y^2 * q_z^2 = 1

예상대로입니다.

감사의 글

Device Orientation and Motion 명세는 2016년 8월 후보 권고안으로 DeviceOrientation Event Specification이라는 제목으로 처음 공개되었으며, Geolocation Working Group에서 처음 개발되었습니다. 2017년 그룹이 해산된 후 명세는 일시적으로 중단되었다가, 2019년 Devices and Sensors Working Group에서 부활되어 상호운용성, 테스트 자동화, 개인정보 보호, 편집 등에서 상당한 개선이 이루어졌습니다(자세한 내용은 § 10 변경사항 섹션 참조).

2024년 Devices and Sensors Working Group은 Web Applications Working Group과 협력하여 이 문서를 공동 산출물로 만들고 명세 발전을 이어가고 있습니다. 초기 설계 논의는 이 GitHub 저장소가 아닌 Geolocation Working Group의 메일링 리스트 아카이브에서 확인할 수 있습니다.

W3C는 Lars Erik Bolstad, Dean Jackson, Claes Nilsson, George Percivall, Doug Turner, Matt Womer, Chris Dumez의 기여에 감사를 표합니다.

10. 변경사항

이 섹션은 검토에 도움이 되도록 주요 변경점과 편집상의 주요 개선 사항을 요약한 것입니다. 자세한 내역은 커밋 로그에서 확인할 수 있습니다. 2016-08-18 후보 권고안 이후의 변경 사항:

적합성

문서 관례

적합성 요구사항은 설명적 단언과 RFC 2119 용어의 조합으로 표현됩니다. 규범적 부분에서 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL"과 같은 주요 단어는 RFC 2119에 설명된 대로 해석되어야 합니다. 하지만 가독성을 위해 이 단어들은 본 명세서에서 모두 대문자로 표기되지는 않습니다.

이 명세서의 모든 텍스트는 명시적으로 비규범적으로 표시된 섹션, 예제, 노트를 제외하고 규범적입니다. [RFC2119]

이 명세서의 예제는 “예를 들어”라는 말로 시작하거나 class="example"로 구분되어 규범 텍스트와 구분됩니다. 예시:

이것은 안내용 예시입니다.

안내용 노트는 “참고”라는 말로 시작하며 class="note"로 규범 텍스트와 구분됩니다. 예시:

참고: 이것은 안내용 노트입니다.

적합 알고리즘

알고리즘의 일부로 명령적으로 표현된 요구사항(예: "앞쪽의 공백 문자 모두 제거" 또는 "false를 반환하고 이 단계를 중단한다")은 도입부에서 사용된 주요 단어("must", "should", "may" 등)의 의미로 해석되어야 합니다.

알고리즘 또는 구체적인 단계로 표현된 적합성 요구사항은 최종 결과가 동등하다면 어떤 방식으로든 구현할 수 있습니다. 특히, 본 명세서에서 정의된 알고리즘은 이해하기 쉽게 설계된 것이며, 성능을 고려한 것이 아닙니다. 구현자에게 최적화를 권장합니다.

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참고문헌

규범적 참고문헌

[ACCELEROMETER]
Anssi Kostiainen. Accelerometer. 2025년 2월 12일. CRD. URL: https://www.w3.org/TR/accelerometer/
[DOM]
Anne van Kesteren. DOM 표준. 현행 표준. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript 언어 명세. URL: https://tc39.es/ecma262/multipage/
[GENERIC-SENSOR]
Rick Waldron. Generic Sensor API. 2024년 2월 22일. CRD. URL: https://www.w3.org/TR/generic-sensor/
[HTML]
Anne van Kesteren; et al. HTML 표준. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 표준. 현행 표준. URL: https://infra.spec.whatwg.org/
[ORIENTATION-SENSOR]
Kenneth Christiansen; Anssi Kostiainen. Orientation Sensor. 2024년 1월 10일. WD. URL: https://www.w3.org/TR/orientation-sensor/
[PERMISSIONS]
Marcos Caceres; Mike Taylor. Permissions. 2024년 12월 20일. WD. URL: https://www.w3.org/TR/permissions/
[PERMISSIONS-POLICY-1]
Ian Clelland. Permissions Policy. 2025년 2월 10일. WD. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
S. Bradner. RFC에서 요구 수준을 표시하는 키워드. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[W3C-PROCESS]
Elika J. Etemad (fantasai); Florian Rivoal. W3C Process Document. 2023년 11월 3일. URL: https://www.w3.org/policies/process/
[WEBDRIVER2]
Simon Stewart; David Burns. WebDriver. 2025년 2월 10일. WD. URL: https://www.w3.org/TR/webdriver2/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 표준. 현행 표준. URL: https://webidl.spec.whatwg.org/

참고용 참고문헌

[CSS-TRANSFORMS-2]
Tab Atkins Jr.; et al. CSS Transforms Module Level 2. 2021년 11월 9일. WD. URL: https://www.w3.org/TR/css-transforms-2/
[EULERANGLES]
Euler 각도. URL: https://en.wikipedia.org/wiki/Euler_angles
[FINGERPRINT]
센서 지문을 통한 모바일 디바이스 식별. 2014년 8월 6일. URL: https://arxiv.org/abs/1408.1416
[G-FORCE]
G-Force. URL: https://en.wikipedia.org/wiki/G-force
[GEOMETRY-1]
Simon Pieters; Chris Harrelson. Geometry Interfaces Module Level 1. 2018년 12월 4일. CR. URL: https://www.w3.org/TR/geometry-1/
[GIMBALLOCK]
짐벌락(Gimbal Lock). URL: https://en.wikipedia.org/wiki/Gimbal_Lock
[GYROSCOPE]
Anssi Kostiainen. Gyroscope. 2024년 10월 8일. CRD. URL: https://www.w3.org/TR/gyroscope/
[INDOORPOS]
Shala, Ubejd; Angel Rodriguez. 안드로이드 디바이스에서 센서 융합을 이용한 실내 위치추적. 2011년. URL: http://www.diva-portal.org/smash/record.jsf?pid=diva2%3A475619&dswid=9050
[MOTION-SENSORS]
Kenneth Christiansen; Alexander Shalamov. Motion Sensors Explainer. 2017년 8월 30일. NOTE. URL: https://www.w3.org/TR/motion-sensors/
[PROPERACCELERATION]
Proper acceleration. URL: https://en.wikipedia.org/wiki/Proper_acceleration
[QUATERNIONS]
Quaternion. URL: https://en.wikipedia.org/wiki/Quaternion
[SCREEN-ORIENTATION]
Marcos Caceres. 화면 방향(Screen Orientation). 2023년 8월 9일. WD. URL: https://www.w3.org/TR/screen-orientation/
[SENSORID]
Zhang, Jiexin; Beresford, Alastair R.; Sheret, Ian. SensorID: 스마트폰을 위한 센서 보정 지문 채취. 2019년. URL: https://doi.org/10.1109/SP.2019.00072
[TOUCH]
TouchSignatures: 자바스크립트를 통한 모바일 센서 데이터 기반 사용자 터치 동작 및 PIN 식별. 2016년 2월 12일. URL: https://arxiv.org/abs/1602.04115

IDL 색인

partial interface Window {
    [SecureContext] attribute EventHandler ondeviceorientation;
};

[Exposed=Window, SecureContext]
interface DeviceOrientationEvent : Event {
    constructor(DOMString type, optional DeviceOrientationEventInit eventInitDict = {});
    readonly attribute double? alpha;
    readonly attribute double? beta;
    readonly attribute double? gamma;
    readonly attribute boolean absolute;

    static Promise<PermissionState> requestPermission(optional boolean absolute = false);
};

dictionary DeviceOrientationEventInit : EventInit {
    double? alpha = null;
    double? beta = null;
    double? gamma = null;
    boolean absolute = false;
};

partial interface Window {
    [SecureContext] attribute EventHandler ondeviceorientationabsolute;
};

[Exposed=Window, SecureContext]
interface DeviceMotionEventAcceleration {
    readonly attribute double? x;
    readonly attribute double? y;
    readonly attribute double? z;
};

[Exposed=Window, SecureContext]
interface DeviceMotionEventRotationRate {
    readonly attribute double? alpha;
    readonly attribute double? beta;
    readonly attribute double? gamma;
};

partial interface Window {
    [SecureContext] attribute EventHandler ondevicemotion;
};

[Exposed=Window, SecureContext]
interface DeviceMotionEvent : Event {
    constructor(DOMString type, optional DeviceMotionEventInit eventInitDict = {});
    readonly attribute DeviceMotionEventAcceleration? acceleration;
    readonly attribute DeviceMotionEventAcceleration? accelerationIncludingGravity;
    readonly attribute DeviceMotionEventRotationRate? rotationRate;
    readonly attribute double interval;

    static Promise<PermissionState> requestPermission();
};

dictionary DeviceMotionEventAccelerationInit {
    double? x = null;
    double? y = null;
    double? z = null;
};

dictionary DeviceMotionEventRotationRateInit {
    double? alpha = null;
    double? beta = null;
    double? gamma = null;
};

dictionary DeviceMotionEventInit : EventInit {
    DeviceMotionEventAccelerationInit acceleration;
    DeviceMotionEventAccelerationInit accelerationIncludingGravity;
    DeviceMotionEventRotationRateInit rotationRate;
    double interval = 0;
};

MDN

DeviceMotionEvent/DeviceMotionEvent

Firefox29+SafariNoneChrome59+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEvent/acceleration

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEvent/accelerationIncludingGravity

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEvent/interval

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEvent/rotationRate

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEvent

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?

Window/devicemotion_event

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEventAcceleration/x

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEventAcceleration/y

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEventAcceleration/z

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEventAcceleration

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEventRotationRate/alpha

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEventRotationRate/beta

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEventRotationRate/gamma

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceMotionEventRotationRate

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceOrientationEvent/DeviceOrientationEvent

Firefox17+SafariNoneChrome59+
Opera?Edge79+
Edge (Legacy)14+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceOrientationEvent/absolute

Firefox6+SafariNoneChrome7+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

DeviceOrientationEvent/alpha

In all current engines.

Firefox6+SafariNoneChrome7+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile?
MDN

DeviceOrientationEvent/beta

In all current engines.

Firefox6+SafariNoneChrome7+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile?
MDN

DeviceOrientationEvent/gamma

In all current engines.

Firefox6+SafariNoneChrome7+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile?
MDN

DeviceOrientationEvent

In all current engines.

Firefox6+SafariNoneChrome7+
Opera15+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView3+Samsung Internet1.0+Opera Mobile14+

Window/deviceorientation_event

In all current engines.

Firefox6+SafariNoneChrome7+
Opera12+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile12+
MDN

Window/devicemotion_event

In all current engines.

Firefox6+SafariNoneChrome31+
Opera?Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Window/deviceorientation_event

In all current engines.

Firefox6+SafariNoneChrome7+
Opera12+Edge79+
Edge (Legacy)12+IE11
Firefox for Android?iOS Safari4.2+Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile12+
MDN

Window/deviceorientationabsolute_event

In only one current engine.

FirefoxNoneSafariNoneChrome50+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?