Can I use Javascript to get the compass heading for iOS and Android?
Asked Answered
E

3

17

Can I use Javascript in a cross-platform way to get the compass heading in iOS and Android (with Chrome), without using something like PhoneGap? I know iOS has DeviceOrientationEvent, but I can't find any equivalent on Chrome for Android.

Eclampsia answered 16/4, 2013 at 22:47 Comment(1)
There is a Web Compass API. I don't know the browser support of it but you can try accessing getCurrentOrientation in global scope and see if it's there. You might also want to try it with webkit prefix. Good luck!Parthena
E
9

Yes you can! Unfortunately the alpha doesn't work on iPhones/iPads. With Mobile Safari, alpha is based on the direction the device was pointing when device orientation was first requested. The included webkit offers you the compass heading. To make it work for all other browsers (which all supports alpha as compassheading) you can use the following Javascript code:

if (window.DeviceOrientationEvent) {
  // Listen for the deviceorientation event and handle the raw data
  window.addEventListener('deviceorientation', function(eventData) {
    var compassdir;

    if(event.webkitCompassHeading) {
      // Apple works only with this, alpha doesn't work
      compassdir = event.webkitCompassHeading;  
    }
    else compassdir = event.alpha;
  });
}

Android also supports Webkit, so would also use event.webkitCompassHeading, but that's OK.

BTW: "oncompassneedscalibration" is also not supported for iPhones and iPads.

Epidemic answered 9/12, 2014 at 22:51 Comment(2)
event.alpha isn't enough to get a compass heading, alpha is just the z rotation of a device on its own axis (see w3c.github.io/deviceorientation/…). It is possible to translate alpha, beta and gamma into a compass heading, though; see the answer from @Unblinking below.Pleura
@davidjb: Your answer might confuse readers without any given explanations and richt example is also related to the alpha channel. Here is a visual example that shows that alpha channel is related to horizontal orientation from holder view: dev.opera.com/articles/w3c-device-orientation-api What you probably wanted to say: In case of using only alpha channel for compass heading you have to hold the phone horizontally and in portrait mode for proper use. Else the phone might got loose its orientation and not showing proper heading.Epidemic
U
23

As a primer you should review this previous related StackOverflow answer and be familiar with the general practical considerations for using DeviceOrientation Events in web applications.

The simple solution I provided in my previous related StackOverflow answer only applies to browsers that implement absolute deviceorientation events (i.e. browsers where the deviceorientation alpha property is compass-oriented). That means the solution provided there currently only works in Android browsers and not iOS-based browsers or any other browser that does not provide absolute-based deviceorientation event data.

To reliably obtain the current compass heading across both Android and iOS browsers today you need to handle both absolute and non-absolute implementations that provide the additional webkitCompassHeading property and make sure to account for any current screen orientation changes as part of that. AFAIK the only library that currently does this is Full Tilt JS (disclaimer: I am the author of this library).

The following code will give you the same correct compass heading across both iOS and Android browsers, taking account of the differences in device orientation implementations and applying any necessary runtime screen orientation transforms too:

<!-- Include the Full Tilt JS library from https://github.com/richtr/Full-Tilt-JS -->
<script src="fulltilt-min.js"></script>

<script>

  // Obtain a new *world-oriented* Full Tilt JS DeviceOrientation Promise
  var promise = FULLTILT.getDeviceOrientation({ 'type': 'world' });

  // Wait for Promise result
  promise.then(function(deviceOrientation) { // Device Orientation Events are supported

    // Register a callback to run every time a new 
    // deviceorientation event is fired by the browser.
    deviceOrientation.listen(function() {

      // Get the current *screen-adjusted* device orientation angles
      var currentOrientation = deviceOrientation.getScreenAdjustedEuler();

      // Calculate the current compass heading that the user is 'looking at' (in degrees)
      var compassHeading = 360 - currentOrientation.alpha;

      // Do something with `compassHeading` here...

    });

  }).catch(function(errorMessage) { // Device Orientation Events are not supported

    console.log(errorMessage);

    // Implement some fallback controls here...

  });

</script>

Here is a demo that demonstrates this technique to obtain the compass heading the user is facing. It should work well on both iOS and Android browsers.

The implementation of the code in that demo is as shown above and can be viewed on Github at ./scripts/compass.js:L268-L272.

Unblinking answered 9/10, 2014 at 10:16 Comment(8)
hello Richt, I have tested your library, works perfectly, but I think it doesn't give me the real North right ?Surprint
none of these examples give the north on android. this is a total joke.Chalcopyrite
@Unblinking after obtaining device orientation , how would i use it to get the compass heading ( direction to geo Point B)? I can successfully calculate bearing(degrees) from 2 geo-points(Point A & Point B).Tapping
This library has a non-commercial licence.Youngstown
An issue on Chrome is waiting for a PR integration since february (may explain some previous comments): Issue github.com/adtile/Full-Tilt/issues/22 PR github.com/adtile/Full-Tilt/pull/25 :-/Annapolis
Hi @Richt, I have checked the demo on two android devices. Both are pointing to different directions but none of them is correct, it's really +/- 180deg. I like your marine compass, but is there a fix to get real north?Burchett
@Unblinking I get "No compass detected" on Chrome and Safari on my iPhone 7 (screenshot). I wonder if mobiles have added data-privacy security measures...Detrition
No compass detected on iPhone 11 chrome browserHarcourt
E
9

Yes you can! Unfortunately the alpha doesn't work on iPhones/iPads. With Mobile Safari, alpha is based on the direction the device was pointing when device orientation was first requested. The included webkit offers you the compass heading. To make it work for all other browsers (which all supports alpha as compassheading) you can use the following Javascript code:

if (window.DeviceOrientationEvent) {
  // Listen for the deviceorientation event and handle the raw data
  window.addEventListener('deviceorientation', function(eventData) {
    var compassdir;

    if(event.webkitCompassHeading) {
      // Apple works only with this, alpha doesn't work
      compassdir = event.webkitCompassHeading;  
    }
    else compassdir = event.alpha;
  });
}

Android also supports Webkit, so would also use event.webkitCompassHeading, but that's OK.

BTW: "oncompassneedscalibration" is also not supported for iPhones and iPads.

Epidemic answered 9/12, 2014 at 22:51 Comment(2)
event.alpha isn't enough to get a compass heading, alpha is just the z rotation of a device on its own axis (see w3c.github.io/deviceorientation/…). It is possible to translate alpha, beta and gamma into a compass heading, though; see the answer from @Unblinking below.Pleura
@davidjb: Your answer might confuse readers without any given explanations and richt example is also related to the alpha channel. Here is a visual example that shows that alpha channel is related to horizontal orientation from holder view: dev.opera.com/articles/w3c-device-orientation-api What you probably wanted to say: In case of using only alpha channel for compass heading you have to hold the phone horizontally and in portrait mode for proper use. Else the phone might got loose its orientation and not showing proper heading.Epidemic
G
-6

I believe you can use the "heading" field of the location object, from navigator.geolocation, please see here:

https://developer.mozilla.org/en-US/docs/WebAPI/Using_geolocation

I know no other way.

Hope it helps, A.

Graehl answered 16/4, 2013 at 22:51 Comment(2)
-1. Geolocation is not giving you Compass data. This is not a real answer.Parthena
The heading attribute denotes the direction of travel, not compass; and is insuitable for use indoors.Streamline

© 2022 - 2024 — McMap. All rights reserved.