Search code examples
jquerycssgyroscopedevice-orientation

jQuery device orientation range converting to percentage between 0 and 100


I'm trying to control an HTML element by using the gyroscope in my smartphone. I managed to extract the gyroscope's values (Alpha, Beta and Gamma) but can't manage to translate it in such a way it's able to manipulate objects the way I'd like to.

The starting position of the device is in landscape mode, right in front of the user; just like a flatscreen television. The device will be inserted in a Google Cardboard viewer.

The attached image explains what I am trying to achieve.

enter image description here

  1. An objects "Left" percentage in CSS.
  2. Device orientation while rotating head from left to right

I can't seem to find a way to "convert" the range of the rotaion movement to a percentage value between 0 and 100%.

For example:

  • If I look slightly left, the Alpha value is around 22/23 and the left percentage should be around 25.
  • If I look slightly right, the Alpha value is around 338/337 and the left percentage should be around 75.

Could you guys help me out?

Best regards,

Peter


Solution

  • You got this a bit wrong, check for more details here: https://developer.mozilla.org/en-US/docs/Web/API/Detecting_device_orientation

    • The DeviceOrientationEvent.alpha value represents the motion of the device around the z axis, represented in degrees with values ranging from 0 to 360.
    • The DeviceOrientationEvent.beta value represents the motion of the device around the x axis, represented in degrees with values ranging from -180 to 180. This represents a front to back motion of the device.
    • The DeviceOrientationEvent.gamma value represents the motion of the device around the y axis, represented in degrees with values ranging from -90 to 90. This represents a left to right motion of the device.

    est-west and north-south position, notice z is not represented in x y axis

    • x - beta: Represents the axis from West to East
    • y - gamma: Represents the axis from South to North
    • z - alpha: Represents the axis perpendicular to the ground

    Going forward with CSS props:

    • x - beta: Represents top property
    • y - gamma: Represents left property
    • z - alpha: not necessary usable in a 2d css but you can use it for zoom or angle to a 2d shape, div or image.

    For left property, you should use gamma device orientation, here is a nice example (masonry level gama) where left css prop in percent is used to position the level point.

    try form here on mobile: https://jsfiddle.net/f7tdrb87/

    percentage computation:

    function precentageIn180(value)
    {
        var percent =  ((value * 100) / 180).toFixed(0);
      return percent;
    }
    

    and the interval [-90, 90] transposed into [0, 180] where 0 == 0% and 180 == 100%, so then event.gamma + 90 is used all the time;

    var point   = document.querySelector('.point');
    var masonryLevel = document.querySelector('.masonry-level-gama');
    var log = document.querySelector('.log');
    
    var maxY = masonryLevel.clientWidth - point.clientWidth;
    
    function precentageIn180(value)
    {
    	var percent =  ((value * 100) / 180).toFixed(0);
      return percent;
    }
    
    function handleOrientation(event) {
      var y = event.gamma; // In degree in the range [-90,90]
      log.innerHTML = "gamma: " + y + "\n";
      //value on gama is [-90, 90] => but we want to have between [0, 180], to be possiblle to compute 100% of 180
      y += 90;
      var percent = precentageIn180(y);
      log.innerHTML += "gamma percent: " + percent + "\n";
      point.style.left = (percent + "%");
    }
    
    
    
    window.addEventListener('deviceorientation', handleOrientation);
    .masonry-level-gama {
      position: relative;
      width : 190px;
      height: 40px;
      border: 1px solid #CCC;
      border-radius: 10px;
    }
    
    .point {
      position: absolute;
      top   : 10px;
      left  : 50%;
      margin-left: -10px;
      width : 20px;
      height: 20px;
      background: blue;
      border-radius: 100%;
    }
    <div class="masonry-level-gama">
      <div class="point"></div>
    </div>
    <pre class="log"></pre>