Brandon Brandon - 4 months ago 45x
Javascript Question

Orbiting around the origin using a device's orientation

I am trying to replicate the functionality of Google's Cardboard Demo "Exhibit" with three.js. I took the starting example straight from the Chrome Experiments web page and just dropped in code to draw a simple triangular pyramid in the


function init() {
renderer = new THREE.WebGLRenderer();
element = renderer.domElement;
container = document.getElementById('example');

effect = new THREE.StereoEffect(renderer);

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera(90, 1, 0.001, 700);
camera.position.set(0, 0, 50);

controls = new THREE.OrbitControls(camera, element);
controls.rotateUp(Math.PI / 4);
controls.noZoom = true;
controls.noPan = true;

var geometry = new THREE.CylinderGeometry( 0, 10, 30, 4, 1 );
var material = new THREE.MeshPhongMaterial( { color:0xffffff, shading: THREE.FlatShading } );

var mesh = new THREE.Mesh( geometry, material );
mesh.matrixAutoUpdate = false;
scene.add( mesh );

var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 1, 1 );
scene.add( light );

light = new THREE.DirectionalLight( 0x002288 );
light.position.set( -1, -1, -1 );
scene.add( light );

light = new THREE.AmbientLight( 0x222222 );
scene.add( light );

function setOrientationControls(e) {
if (!e.alpha) {

controls = new THREE.DeviceOrientationControls(camera);

element.addEventListener('click', fullscreen, false);

window.removeEventListener('deviceorientation', setOrientationControls, true);
window.addEventListener('deviceorientation', setOrientationControls, true);

window.addEventListener('resize', resize, false);
setTimeout(resize, 1);

method on desktop works perfectly: by dragging with the mouse, the screen orbits around the pyramid. On mobile using
however, this effect is entirely lost and instead the camera moves freely at (0, 0, 0). I tried doing as a previous question suggested and replacing the
such that:

controls = new THREE.DeviceOrientationControls(scene);

however this does not work at all and nothing moves when the device is rotated. What do I need to change to replicate
behavior with the motion captured by


To create a deviceorientation orbit controler, like you see on this demo,; It involves modifying the existing OrbitControls.js.

The file changes can be seen in this commit on github:

I've been meaning to do a pull request for months. Just haven't gotten around to it. Needs a bunch of clean up.

You can download my modified OrbitControls.js here (I haven't merged in months either, results may vary):

Below is how you would implement the modified OrbitControls in your own scripts:

this.controls = new THREE.OrbitControls( camera, document.getElementById('screen') ) ;

            controls.tiltEnabled = true ;  // default is false.  You need to turn this on to control with the gyro sensor.

            controls.minPolarAngle = Math.PI * 0.4; // radians
            controls.maxPolarAngle = Math.PI * 0.6; // radians
            controls.noZoom = true ;

            // How far you can rotate on the horizontal axis, upper and lower limits.
            // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
            controls.minAzimuthAngle = - Math.PI * 0.1; // radians
            controls.maxAzimuthAngle = Math.PI * 0.1; // radians

            this.UMLogo = scene.children[1];
   = UMLogo.position;

I hope that gets you where you want to be! :-)