Skip to content

Instantly share code, notes, and snippets.

@richtr
Created September 23, 2014 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save richtr/eda598ad98b11f5d7660 to your computer and use it in GitHub Desktop.
Save richtr/eda598ad98b11f5d7660 to your computer and use it in GitHub Desktop.
A reliable DeviceOrientation and DeviceMotion Events API feature detection library
/**
* DeviceOrientation and DeviceMotion Events Detection API
*
* Example API Usage (Promise-based API):
*
* supportsDeviceOrientationEvents().then(function() {
* console.log("Platform DeviceOrientation Events support OK");
* }, function(error) {
* console.error("Platform DeviceOrientation Events support KO");
* });
*
**/
(function() {
var SENSOR_TYPE = [
{
name: "deviceorientation",
testPaths: [["alpha"]],
isSupported: undefined
},
{
name: "devicemotion",
testPaths: [["acceleration", "x"], ["accelerationIncludingGravity", "x"]],
isSupported: undefined
}
];
function SensorCheck(sensor, successCallback, errorCallback) {
// We only need to run each sensor check once per page load
// so this is a neat performance optimization
if (sensor.isSupported === true) {
successCallback.call(this);
return;
} else if (sensor.isSupported === false) {
errorCallback.call(this);
return;
}
var e = {};
var read = function(evt) { e = evt; };
window.addEventListener(sensor.name, read, false);
var c = 0;
// Recursive IIFE sensor data checker
(function runCheck() {
setTimeout(function(){
if (++c === 10) { // run test 10 times then time out
sensor.isSupported = false;
errorCallback.call(this);
window.removeEventListener(sensor.name, read, false);
return;
}
if (e === undefined || e === null) {
runCheck();
return;
}
try {
// Test that all of the event object property paths
// are defined and not null
for (var i = 0, l = sensor.testPaths.length; i < l; i++) {
var testObj = e;
sensor.testPaths[i].forEach(function(val) {
testObj = testObj[val];
if (testObj === undefined || testObj === null) {
runCheck();
throw BreakException;
}
});
}
sensor.isSupported = true;
successCallback.call(this);
window.removeEventListener(sensor.name, read, false);
} catch(e) {}
}, 100);
})();
};
// Add Sensor Test Promise APIs to DOM if they don't already exist
if (!window.supportsDeviceOrientationEvents) {
window.supportsDeviceOrientationEvents = function() {
return new Promise(function(resolve, reject) {
new SensorCheck(SENSOR_TYPE[0], resolve, reject);
});
};
}
if (!window.supportsDeviceMotionEvents) {
window.supportsDeviceMotionEvents = function() {
return new Promise(function(resolve, reject) {
new SensorCheck(SENSOR_TYPE[1], resolve, reject);
});
};
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment