workshop icon indicating copy to clipboard operation
workshop copied to clipboard

Compass example has limited browser support

Open mike-000 opened this issue 3 years ago • 2 comments

The compass example depends on the requestPermission method which currently has limited browser support. On other browsers/devices either no extra permissions are needed or a request is triggered by window.addEventListener('deviceorientation'). A more generic solution which maintains the existing structure might look like

if (window.DeviceOrientationEvent) {
  locate.addEventListener('click', function () {
    Promise.resolve(
      typeof DeviceOrientationEvent.requestPermission === 'function'
        ? DeviceOrientationEvent.requestPermission()
        : ''
    )

mike-000 avatar Mar 15 '22 14:03 mike-000

I don't have that many different devices available. Do you? If so, would you mind testing this?

function initCompass() {
  const compass = new Kompas();
  compass.watch();
  compass.on('heading', function (heading) {
    style.getImage().setRotation((Math.PI / 180) * heading);
  });
}

locate.addEventListener('click', function () {
  if (
    window.DeviceOrientationEvent &&
    typeof DeviceOrientationEvent.requestPermission === 'function'
  ) {
    DeviceOrientationEvent.requestPermission()
      .then(initCompass)
      .catch(function (error) {
        alert(`ERROR: ${error.message}`);
      });
  } else {
    initCompass();
  }
});

ahocevar avatar Mar 15 '22 14:03 ahocevar

That is almost the method I used to get it working on Android with Chrome - although I put the window.DeviceOrientationEvent check outside the whole block that was probably being over-cautious - the only browser which doesn't have DeviceOrientationEvent seems to be Safari for Mac. I don't have that but I don't think adding an listener for a non-existent event type causes errors on any browser?

Your proposed update certainly works with Chrome 99 Android 12 and also Chrome 81 Android 4.4

image

My application was using EPSG:27700. At the extremities there is a noticeable different between true and grid north and additional calculation is needed to align the compass correctly

image

smBottom = ol.proj.transform([point[0], point[1] - 100], viewProjection, 'EPSG:3857');
smTop = ol.proj.transform([point[0], point[1] + 100], viewProjection, 'EPSG:3857');
variation = Math.atan2(smBottom[0] - smTop[0], smTop[1] - smBottom[1]);
style.getImage().setRotation(variation + heading);

mike-000 avatar Mar 15 '22 23:03 mike-000