65 lines
1.5 KiB
JavaScript
65 lines
1.5 KiB
JavaScript
(function (ns) {
|
|
'use strict';
|
|
|
|
let listener = null;
|
|
const eventNames = ['deviceorientationabsolute', 'deviceorientation'];
|
|
let callback = null;
|
|
|
|
function normalizeDegrees(value) {
|
|
return (value % 360 + 360) % 360;
|
|
}
|
|
|
|
function readHeading(event) {
|
|
if (Number.isFinite(event.webkitCompassHeading)) {
|
|
return normalizeDegrees(event.webkitCompassHeading);
|
|
}
|
|
|
|
if ((event.absolute || event.type === 'deviceorientationabsolute') && Number.isFinite(event.alpha)) {
|
|
return normalizeDegrees(360 - event.alpha);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
async function requestPermission() {
|
|
const orientation = window.DeviceOrientationEvent;
|
|
if (!orientation) return false;
|
|
|
|
if (typeof orientation.requestPermission === 'function') {
|
|
return (await orientation.requestPermission()) === 'granted';
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
ns.Orientation = {
|
|
async start(onHeading) {
|
|
this.stop();
|
|
callback = onHeading;
|
|
|
|
let permitted = false;
|
|
try {
|
|
permitted = await requestPermission();
|
|
} catch {
|
|
permitted = false;
|
|
}
|
|
|
|
if (!permitted) return false;
|
|
|
|
listener = event => {
|
|
const heading = readHeading(event);
|
|
if (heading != null) callback?.(heading);
|
|
};
|
|
|
|
eventNames.forEach(name => window.addEventListener(name, listener, true));
|
|
return true;
|
|
},
|
|
|
|
stop() {
|
|
if (listener) eventNames.forEach(name => window.removeEventListener(name, listener, true));
|
|
listener = null;
|
|
callback = null;
|
|
}
|
|
};
|
|
}(window.Wegwichtel));
|