Tween camera in response to mousemove event

camera-controls

#1

First off, thanks for being a great open-source community committed to this totally cool technology.
Secondly, feel free to disregard this question/let me know if this is not the appropriate forum for it.

Ok, so I have some code for tweening a camera in response to user input in a kinda tasteful, slow-mo way, and I’m suspicious that my way of accomplishing it is not the optimal way to do it. Was wondering if anyone would like to take a look at it and gimme some tips on how to make it more performant, and clue me in on the relevant best practices to follow. Here’s the code:

$(document).ready(function () {
//init variables
var scene = new THREE.Scene();  
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0,0,5);
var mousePos = new THREE.Vector3();

$('body').mousemove(_.throttle(onMouseMove, 100));
var width = window.innerWidth;
var height = window.innerHeight;

function onMouseMove(event) {
  console.log(event.clientX);
  console.log(event.clientY);
    TweenMax.to(mousePos, 5, {
        x: (event.clientX / width) * 2 - 1,
        y: -((event.clientY / height) * 2 - 1),
        onUpdate: function () {
            camera.lookAt(mousePos);
        }
    });
}

var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setClearColor(0xffffff, 1);

var cubeGeometry = new THREE.BoxGeometry(3, 3, 3);
var cubeMaterial = new THREE.MeshBasicMaterial({ color: 0x909090 });
var cubeMesh = new THREE.Mesh(cubeGeometry, cubeMaterial);
var cube = new THREE.Object3D();
cube.add(cubeMesh);

cube.position.x = 0;
cube.position.y = 0;
cube.position.z = -5;

cube.rotation.y = Math.random();
cube.rotation.x = Math.random();
scene.add(cube);


// Animate the scene

var animate = function () {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
};

animate();

// Draw it in the dom and add resize event listener

$('body').append(renderer.domElement);

window.addEventListener('resize', onWindowResize, false);

});

Here’s a codepen with the dependencies included in case you wanna mess around with it.


#2

You can achieve a similar effect in a more lightweight fashion. Check out the code of this example (especially the onDocumentMouseMove() and render() function):

https://threejs.org/examples/#webgl_materials_bumpmap

The code does not change the camera but rotates the model according to the user input.


#3

You might also have a look at the various control classes of three.js. All these entities change the transformation of the camera based on user input.


#4

Thanks, these camera controls files are especially helpful.