1

I want to show a cup of water in my web page.I want when the user rotate their device, the water should go down to the horizon line as natural.

window.addEventListener('deviceorientation', this.handleOrientation.bind(this));

handleOrientation(orientData) {
    var absolute = orientData.absolute;
    var alpha = orientData.alpha;
    var beta = orientData.beta;
    var gamma = orientData.gamma;
}

From the api above , I can get those four angle information. But I don't know how to get the current angle from the device to the horizon line so that I could set my water to rotate to the horizon line.

shadox
  • 997
  • 1
  • 8
  • 18

1 Answers1

3

Based on the the example from MDN and a bit of trigonometry I was able to come up with the code below. I successfully tested this on Chrome on Android, Firefox sadly wouldn't fire the deviceorientation event (even the example on MDN didn't work).

The other caveat is screen orientation, i.e. if your device is currently in landscape mode. Old APIs (window.orientation) are unsupported in some browsers, new APIs (screen.orientation) haven't been fully implemented and behave differently.

var watercup = document.querySelector('#watercup');

function handleOrientation(event) {
  var x = event.beta;  // In degree in the range [-180,180], x, 'front to back'
  var y = event.gamma; // In degree in the range [-90,90], y, 'left to right'
  var z = event.alpha; // 0-360, z, compass orientation

  // coord 1: 0,0
  // coord 2: x,y
  // calculate the angle
  var rad = Math.atan2(y, x);
  var deg = rad * (180 / Math.PI);

  // take into account if phone is held sideways / in landscape mode
  var screenOrientation = screen.orientation || screen.mozOrientation || screen.msOrientation;
  // 90, -90, or 0
  var angle = screenOrientation.angle || window.orientation || 0; 
  
  deg = deg + angle; 

  watercup.innerHTML = Math.round(deg);
  watercup.style.transform = 'rotate('+ -deg +'deg)';
}

window.addEventListener('deviceorientation', handleOrientation);
#watercup {
  border:2px solid #aaa;
  width:100px;
  height:200px;
  background: linear-gradient(to bottom, white 20%, lightblue 20%, blue);
  margin: 20px auto;
}
<div id="watercup"></div>
Community
  • 1
  • 1
chrki
  • 6,143
  • 6
  • 35
  • 55
  • Whenver I rotate my S7 counter-clockwise, the calculated degrees angle jumps from 60 to 35, the same failure occurs clockwise, skipping from -60 to -35. Any ideas why this happens? I have a **Protractor app** that measures all 360 angles perfectly fine, so the sensors are not the problem. Thanks for the detailed reply anyway, it almost worked perfectly! – andreszs Feb 11 '21 at 14:01
  • Is there any chance someone could explain (leaving aside screen orientation angle) why `atan2(gamma, beta)` yields the needed angle? BTW I'm not totally rusty with trigonometrics. `atan2(y, x)` works with (x, y) coordinates of a point. How can beta and gamma angles be interpreted as coordinates? And then why that combination gives the needed angle? For references, I'm aware of [this](https://developer.mozilla.org/en-US/docs/Web/API/Device_orientation_events/Orientation_and_motion_data_explained) and [this](https://en.wikipedia.org/wiki/File:Eulerangles.svg). Thanks – superjos Feb 08 '23 at 21:41