mozilla
Your Search Results

    Using device orientation with 3D transforms Redirect 2

    This article provides tips on how to use device orientation information in tandem with CSS 3D transforms.

    Using orientation to rotate an element

    The easiest way to convert orientation data to a 3D transform is basically to use the alpha, gamma, and beta values as rotateZ, rotateX and rotateY values. There are however two corrections that should be applied to those values:

    1. The initial alpha value is 180 (device flat on the back, top of the screen pointing 12:00), so the rotateZ value should be alpha - 180
    2. The Y axis of the screen coordinate system is inverted, such that translateY(100px) moves an element 100px down, so the rotateY value should be -gamma

    Finally, the order of the three different rotations is very important to accurately convert an orientation to a 3D rotation: rotateZ, then rotateX and then rotateY. Here's a simple code snippet to sum it up:

    var elem = document.getElementById("view3d");
    
    window.addEventListener("deviceorientation", function(e) {
      // remember to use vendor-prefixed transform property
      elem.style.transform =
        "rotateZ(" + ( e.alpha - 180 ) + "deg) " +
        "rotateX(" + e.beta + "deg) " +
        "rotateY(" + ( -e.gamma ) + "deg)";
    });
    

    Orientation compensation

    Compensating the orientation of the device can be useful to create parallax effects or augmented reality. This is achieved by inverting the previous order of rotations and negating the alpha value:

    var elem = document.getElementById("view3d");
    
    window.addEventListener("deviceorientation", function(e) {
      // again, use vendor-prefixed transform property
      elem.style.transform =
        "rotateY(" + ( -e.gamma ) + "deg)" +
        "rotateX(" + e.beta + "deg) " +
        "rotateZ(" + - ( e.alpha - 180 ) + "deg) ";
    });
    

    You can test this code in an "orientation-aware" mobile browser such as Firefox Mobile with this demo of orientation compensation.

    rotate3d to orientation

    Should you ever need to convert a rotate3d axis-angle to orientation Euler angles, you can use the following algorithm:

    // convert a rotate3d axis-angle to deviceorientation angles
    function orient( aa ) {
        var x = aa.x, y = aa.y, z = aa.z, a = aa.a,
            c = Math.cos( aa.a ),
            s = Math.sin( aa.a ),
            t = 1 - c,
            // axis-angle to rotation matrix
            rm00 =    c + x*x * t,
            rm10 =  z*s + y*x * t,
            rm20 = -y*s + z*x * t,
            rm01 = -z*s + x*y * t,
            rm11 =    c + y*y * t,
            rm21 =  x*s + z*y * t,
            rm02 =  y*s + x*z * t,
            rm12 = -x*s + y*z * t,
            rm22 =    c + z*z * t,
            
            TO_DEG = 180 / Math.PI,
            ea = [],
            n = Math.sqrt( rm22 * rm22 + rm20 * rm20 );
    
        // rotation matrix to Euler angles
        ea[1] = Math.atan2( -rm21, n );
    
        if ( n > 0.001 ) {
            ea[0] = Math.atan2( rm01, rm11 );
            ea[2] = Math.atan2( rm20, rm22 );
    
        } else {
            ea[0] = 0;
            ea[2] = ( rm21 > 0 ? 1 : -1 ) * Math.atan2( -rm10, rm00 );
        }
    
        return {
            alpha: -ea[0] * TO_DEG - 180,
            beta:  -ea[1] * TO_DEG,
            gamma:  ea[2] * TO_DEG
        };
    }
    

    See also

    Document Tags and Contributors

    Contributors to this page: Sheppy
    Last updated by: Sheppy,