Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing hardware support in Javascript for device orientation events of the iPhone 3GS

I'm trying to use HTML5 deviceOrientation events in Javascript to rotate an image when the user rotate his iPhone around him.

I use this code to detect when the gyroscope is moving :

window.addEventListener('deviceorientation', function (e) {
    alpha = e.alpha;
    beta = e.beta;
    gamma = e.gamma;            
}, true);

It really works well on iPhone 4+ and iPad 2, but there's no gyroscope on the 3GS (and older iPhones). That's why I'm testing the deviceOrientationSupport like this :

if(window.DeviceOrientationEvent){ // gyroscope support
    alert('DeviceOrientationEvent support OK');
} else {
    alert('DeviceOrientationEvent support KO');
}

I've seen this code on many websites or forums, but my problem is that with my iPhone 3GS under IOS 5.0.1, this test indicates me : deviceOrientationSupport OK !

I think that this test check only if Safari is able to handle these events :(

So my question is, is it possible to add a test to know if the hardware can fire orientation events ?

Thanks !

like image 613
MavBzh Avatar asked Jan 31 '12 09:01

MavBzh


2 Answers

I hope this isn't coming at you too late, but isn't it frustrating that Safari for iOS 4.2+ will register DeviceOrientationEvent on an iPhone 3GS (or other devices without a gyroscope)?

Bottom Line, DeviceOrientation does not work with the iPhone 3GS. But as someone mentioned, DeviceMotionEvent works, but you have to access the event data in a different way than you would with a device with a gyroscope (silly I know!).

First Step: I added a variable in the mix to capture whether or not the OrientationEvent was actually firing with any non-null data (as it would if there were a gyroscope).

var canHandleOrientation;
if (window.DeviceOrientationEvent) {
    window.addEventListener("deviceorientation", handleOrientation, false);
}

function handleOrientation(event){
  console.log("Orientation:" + event.alpha + ", " + event.beta + ", " + event.gamma);
  canHandleOrientation = event; // will be either null or with event data
}

Now you know whether or not the event actually has gyroscope data or not! So if you want to default to something else (ie. window.DeviceMotionEvent) you can use a conditional.

if (!canHandleOrientation) {
  console.log("There is no gyroscope")
}

I tested this on Mobile Safari for iPhone 3GS (no gyroscope) and iPad 2 (gyroscope) and Chrome on my Macbook Pro (gyroscope). Seems to work.

Now, if you want to get the DeviceMotionEvent data as an alternative if the Orientation data is not available, then...

if (window.DeviceMotionEvent && !canHandleOrientation) {
  window.addEventListener('devicemotion', handleMotion, false);
}

function handleMotion(event){
  if(event.acceleration){
    //requires a gyroscope to work.
    console.log("Motion Acceleration: " +  event.acceleration.x + ", " +  event.acceleration.y + ", " +  event.acceleration.z);
  }
  else{
    //this is for iPhone 3GS or a device with no gyroscope, and includes gravity.
    console.log("Motion AccelerationGravity: " + event.accelerationIncludingGravity.x + ", " + event.accelerationIncludingGravity.y + ", " + event.accelerationIncludingGravity.z);
  }
}

This should cover your bases for most devices with a webkit browser... I hope. Havent tested it on any Android devices.

It should be noted, each event returns different numbers, so you might need to do some work to normalize them. But this is the basics of how you access them.

Let me know if this helps!

like image 55
Arjun Mehta Avatar answered Oct 02 '22 15:10

Arjun Mehta


After having the same issue as above I also had problems with the older iPad/iPhones not even calling the function on addEventListener.

So I found that the following worked a lot better for me and eliminated any chance of an unsupported device getting through (this was sat with a load screen so it did require an interval before completing its full test. So not for everyone).

var _i = null;
var _e = null;
var _c = 0;

var updateDegree = function(e){
    _e = e;
}

window.addEventListener('deviceorientation', updateDegree, false);

//  Check event support
_i = window.setInterval(function(){
    if(_e !== null && _e.alpha !== null){
        // Clear interval
        clearInterval(_i);
        // > Run app
    }else{
        _c++;
        if(_c === 10){
            // Clear interval
            clearInterval(_i);
            // > Redirect
        }
    }
}, 200);
like image 27
Ricardinho Avatar answered Oct 02 '22 15:10

Ricardinho