diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..9225c67 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +root = true + +[*] +indent_style = space +indent_size = 3 diff --git a/demos/device-orientation-api-demo.html b/demos/device-orientation-api-demo.html index 33aa1a4..eae8773 100644 --- a/demos/device-orientation-api-demo.html +++ b/demos/device-orientation-api-demo.html @@ -27,7 +27,7 @@ line-height: 150px; background-color: #999999; box-shadow: inset 0 0 20px #333333; - opacity: 0.6; + opacity: 0.9; } .cube .one @@ -129,17 +129,112 @@ <h1>Device Orientation API</h1> </small> <script> + // + // 3D Transform code for handling the cube rotation. + // Based on https://dev.opera.com/articles/w3c-device-orientation-usage/ + // + + var degtorad = Math.PI / 180; + + function convertToRotationMatrix(alpha, beta, gamma) { + var _x = beta * degtorad; + var _y = gamma * degtorad; + var _z = alpha * degtorad; + + var cX = Math.cos(_x); + var cY = Math.cos(_y); + var cZ = Math.cos(_z); + var sX = Math.sin(_x); + var sY = Math.sin(_y); + var sZ = Math.sin(_z); + + // ZXY-ordered rotation matrix construction. + + var m11 = cZ * cY - sZ * sX * sY; + var m12 = - cX * sZ; + var m13 = cY * sZ * sX + cZ * sY; + + var m21 = cY * sZ + cZ * sX * sY; + var m22 = cZ * cX; + var m23 = sZ * sY - cZ * cY * sX; + + var m31 = - cX * sY; + var m32 = sX; + var m33 = cX * cY; + + return [ + m11, m12, m13, + m21, m22, m23, + m31, m32, m33 + ]; + } + + function getScreenOrientationRotationMatrix(screenOrientation) { + var orientationAngle = screenOrientation * degtorad; + + var cA = Math.cos(orientationAngle); + var sA = Math.sin(orientationAngle); + + return [ + cA, -sA, 0, + sA, cA, 0, + 0, 0, 1 + ]; + } + + function matrixMultiply(a, b) { + return [ + a[0] * b[0] + a[1] * b[3] + a[2] * b[6], + a[0] * b[1] + a[1] * b[4] + a[2] * b[7], + a[0] * b[2] + a[1] * b[5] + a[2] * b[8], + + a[3] * b[0] + a[4] * b[3] + a[5] * b[6], + a[3] * b[1] + a[4] * b[4] + a[5] * b[7], + a[3] * b[2] + a[4] * b[5] + a[5] * b[8], + + a[6] * b[0] + a[7] * b[3] + a[8] * b[6], + a[6] * b[1] + a[7] * b[4] + a[8] * b[7], + a[6] * b[2] + a[7] * b[5] + a[8] * b[8] + ]; + } + + function computeCubeRotationMatrix(alpha, beta, gamma) { + var rotationMatrix = convertToRotationMatrix(-alpha, -beta, gamma); + + var screenTransform = getScreenOrientationRotationMatrix(window.orientation || 0); + var screenAdjustedMatrix = matrixMultiply(rotationMatrix, screenTransform); + + return screenAdjustedMatrix; + } + + function convertRotationMatrixToTransform(r) { + return [ + r[0], r[1], r[2], 0, + r[3], r[4], r[5], 0, + r[6], r[7], r[8], 0, + 0, 0, 0, 1 + ]; + } + + function convertRotationMatrixToCssTransform(rotationMatrix) { + var transformMatrix = convertRotationMatrixToTransform(rotationMatrix); + return "matrix3d(" + transformMatrix.join(', ') + ")"; + } + + // + // HTML5 API Usage + // + if (!('ondeviceorientation' in window)) { document.getElementById('do-unsupported').classList.remove('hidden'); } else { document.getElementById('do-info').classList.remove('hidden'); window.addEventListener('deviceorientation', function(event) { + var matrix = computeCubeRotationMatrix(event.alpha, event.beta, event.gamma); + var cssMatrix = convertRotationMatrixToCssTransform(matrix); document.getElementById('cube').style.webkitTransform = - document.getElementById('cube').style.transform = - 'rotateX(' + event.beta + 'deg) ' + - 'rotateY(' + event.gamma + 'deg) ' + - 'rotateZ(' + event.alpha + 'deg)'; + document.getElementById('cube').style.transform = cssMatrix; document.getElementById('beta').innerHTML = Math.round(event.beta); document.getElementById('gamma').innerHTML = Math.round(event.gamma);