three.orientation
Version:
Control three.js camera with device orientation API
97 lines (75 loc) • 3.17 kB
JavaScript
/* globals THREE, window */
/**
* @author richt / http://richt.me
* @author WestLangley / http://github.com/WestLangley
*
* @author Andrei Kashcha / https://github.com/anvaka:
* + adopted to commonjs,
* + restructured to avoid `this`
* + preserve original object rotation
* + original source code is here: http://threejs.org/examples/js/controls/DeviceOrientationControls.js
*
* W3C Device Orientation control (http://w3c.github.io/deviceorientation/spec-source-orientation.html)
*/
module.exports = orientationControl;
var degreeToRadiansFactor = Math.PI / 180;
function degToRad(degrees) {
return degrees * degreeToRadiansFactor;
}
function orientationControl(object) {
object.rotation.reorder("YXZ");
var enabled = false;
var deviceOrientation = {};
var screenOrientation = 0;
var originalRotation;
var setObjectQuaternion = createObjectQuaterionSetter();
connect();
return {
update: update,
connect: connect,
disconnect: disconnect,
};
function connect() {
deviceOrientation = {};
originalRotation = object.quaternion.clone();
onScreenOrientationChangeEvent(); // run once on load
window.addEventListener('orientationchange', onScreenOrientationChangeEvent, false);
window.addEventListener('deviceorientation', onDeviceOrientationChangeEvent, false);
enabled = true;
}
function disconnect() {
enabled = false;
window.removeEventListener('orientationchange', onScreenOrientationChangeEvent, false);
window.removeEventListener('deviceorientation', onDeviceOrientationChangeEvent, false);
}
function update() {
if (!enabled) return;
var alpha = deviceOrientation.alpha ? degToRad(deviceOrientation.alpha) : 0; // Z
var beta = deviceOrientation.beta ? degToRad(deviceOrientation.beta) : 0; // X'
var gamma = deviceOrientation.gamma ? degToRad(deviceOrientation.gamma) : 0; // Y''
var orient = screenOrientation ? degToRad(screenOrientation) : 0; // O
setObjectQuaternion(object.quaternion, alpha, beta, gamma, orient);
}
function onDeviceOrientationChangeEvent(event) {
deviceOrientation = event;
}
function onScreenOrientationChangeEvent() {
screenOrientation = window.orientation || 0;
}
function createObjectQuaterionSetter() {
var deviceEuler = new THREE.Euler();
var deviceQuaternion = new THREE.Quaternion();
var screenTransform = new THREE.Quaternion();
var worldTransform = new THREE.Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)); // - PI/2 around the x-axis
var minusHalfAngle = 0;
return function(quaternion, alpha, beta, gamma, orient) {
quaternion.copy(originalRotation);
deviceEuler.set(beta, alpha, -gamma, 'YXZ'); // 'ZXY' for the device, but 'YXZ' for us
quaternion.multiply(deviceQuaternion.setFromEuler(deviceEuler)); // orient the device
minusHalfAngle = -orient / 2;
screenTransform.set( 0, Math.sin( minusHalfAngle ), 0, Math.cos( minusHalfAngle ) );
quaternion.multiply(screenTransform); // adjust for screen orientation
quaternion.multiply(worldTransform); // camera looks out the back of the device, not the top
};
}
}