Upon deep investigation into this matter, I've come to realize that it involves some complex mathematics. If you're interested, I recommend watching this lecture on quaternions:
https://www.youtube.com/watch?v=mHVwd8gYLnI
Following @bjorke's advice, I employed a dummy object and it worked like a charm.
var container, scene, camera, renderer, controls, stats;
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
camera.position.set(100, 100, 400);
camera.lookAt(scene.position);
scene.add(camera);
renderer = new THREE.WebGLRenderer( {antialias:true} );
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
container = document.getElementById( 'ThreeJS' );
container.appendChild( renderer.domElement );
var light = new THREE.DirectionalLight(0xffffff); //new THREE.PointLight(0xffffff);
light.position.set( 30, 80, -15 );
scene.add(light);
var boxGeo = new THREE.BoxGeometry( 10, 10, 10);
var axes = new THREE.AxisHelper(1000);
scene.add( axes );
var cameraObj = new THREE.Mesh(boxGeo, new THREE.MeshLambertMaterial( {color: 0x888800}));
scene.add(cameraObj);
var orbSpace = new THREE.Object3D();
scene.add(orbSpace);
var orbBall = new THREE.Mesh(boxGeo, new THREE.MeshLambertMaterial( {color: 0x880088}));
orbBall.position.set(0, 0, cameraObj.position.z + 100);
orbSpace.add(orbBall);
animate();
var camX = 0.3;
var camY = 0;
function animate() {
requestAnimationFrame( animate );
camY += 0.02;
if (camY >= 2) camY = 0;
cameraObj.rotation.x = Math.PI * document.querySelector('#volume').value;
cameraObj.rotation.y = Math.PI * camY;
orbSpace.position.copy(cameraObj.position);
orbSpace.rotation.copy(cameraObj.rotation)
renderer.render( scene, camera );
}
If you're curious about how it operates, check out this codepen:
http://codepen.io/arpo/pen/RrpMJJ
You can adjust the X angle in the upper right corner