We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

# Using device orientation with 3D transforms Redirect 1

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");

// 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");

// 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
};
}
```