Access compass data in Mobile Web / HTML5

让人想犯罪 __ 提交于 2020-05-28 05:06:06

问题


I'm making AR Mobile Web App, and my current goal is to show some events on the camera screen. For example, if there is fire in direction north from me, I want to point phone to north, and fire logo should be visible there.

My problem is - how can I get the absolute compass data?

I've tried this JavaScript code:

function compassHeading(alpha, beta, gamma) {

  var dataContainerMotion = document.getElementById('dataContainerMotion');

  // Convert degrees to radians
  var alphaRad = alpha * (Math.PI / 180);
  var betaRad = beta * (Math.PI / 180);
  var gammaRad = gamma * (Math.PI / 180);

  // Calculate equation components
  var cA = Math.cos(alphaRad);
  var sA = Math.sin(alphaRad);
  var cB = Math.cos(betaRad);
  var sB = Math.sin(betaRad);
  var cG = Math.cos(gammaRad);
  var sG = Math.sin(gammaRad);

  // Calculate A, B, C rotation components
  var rA = - cA * sG - sA * sB * cG;
  var rB = - sA * sG + cA * sB * cG;
  var rC = - cB * cG;

  // Calculate compass heading
  var compassHeading = Math.atan(rA / rB);

  // Convert from half unit circle to whole unit circle
  if(rB < 0) {
    compassHeading += Math.PI;
  }else if(rA < 0) {
    compassHeading += 2 * Math.PI;
  }

  // Convert radians to degrees
  compassHeading *= 180 / Math.PI;

  return compassHeading;

}

window.addEventListener('deviceorientation', function(evt) {

  heading = compassHeading(alpha, beta, gamma);

  dataContainerMotion.innerHTML = heading;

}, false);

But variable absolute shows false, and I can't get absolute value. Compass is calibrated according to the positioning of the phone on initialization of the page - not according to actual position of the North on the Earth.

I would appreciate any kind of help - I'm stuck here and I can't go further without getting the compass data.


回答1:


You have not mentioned the mobile device you have tested with. There are some major "problems" you have to consider:

  • Alpha on iOS (iPhone, iPad) devices has the value = 0 from where you start/activate the deviceorientation event. If the phone is currently heading to East then Alpha is 0 at East. If your phone is heading to W then Alpha is 0 at West, etc.
  • There is no way to access the implemented hardware compass in Android devices (by Javascript). Some browsers (versions) handle the calculated values alpha, beta and gamma different, so you might have to add/distract a specific angle value. This is also mentioned in the MDN Web Docs
  • Chrome (50+) supports the event "ondeviceorientationabsolute" that might your work easier (at least for Chrome)

Solution for iOS devices:

window.addEventListener('deviceorientation', function(event) {
  if (event.webkitCompassHeading) {
    // You may consider adding/distracting landscape/portrait mode value here
    alpha = event.webkitCompassHeading;
    if (alpha < 0) { alpha += 360; }
    if (alpha > 360) { alpha -= 360; }
  }
}  

Solution for Android devices:

Use alpha/beta/gamma values (as you did). There are already many good solutions around. The "best" (imho) can be found here represented by the TILT compass: mentioned here or directly on GitHub

Considering your code (I haven't checked in detail) is that it won't working properly on iOS devices and probably not even on all Android devices. So all over use a construct like Frosty Z mention in the link posted above.

Sadly there is no 100% reliable code around covering all types of devices and browsers. I still hope something written here might help.



来源:https://stackoverflow.com/questions/49696561/access-compass-data-in-mobile-web-html5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!