tobiasg
tobiasg

Reputation: 1073

Follow mouse position with light in three.js

I have just recently started to explore the world of three.js and I am trying to achieve a solution similar to this old topic regarding basically the same thing, but not quite.

I want to place a sphere in the middle of the scene that's static and still. When moving the mouse, I want the point light of the scene to follow the mouse movement. In the example above, it's the opposite.

I've just started to learn JavaScript and jQuery, so I'm having some trouble understanding the logic of three.js. This is my code so far, but it's not working at all:

// Define the standard global variables
var container,
scene, 
camera,
renderer,
plane,
mouseMesh;

// Custom global variables
var mouse = {x: 0, y: 0};

init();
animate();

function init() {

// Scene
scene = new THREE.Scene();

window.addEventListener('resize', function() {
  var WIDTH = window.innerWidth,
      HEIGHT = window.innerHeight;
  renderer.setSize(WIDTH, HEIGHT);
  camera.aspect = WIDTH / HEIGHT;
  camera.updateProjectionMatrix();
});

// Camera
var screenWidth = window.innerWidth,
        screenHeight = window.innerHeight,
        viewAngle = 75,
        nearDistance = 0.1,
        farDistance = 1000;
camera = new THREE.PerspectiveCamera(viewAngle, screenWidth /   screenHeight, nearDistance, farDistance);
scene.add(camera);
camera.position.set(0, 0, 5);
camera.lookAt(scene.position);

// Renderer engine together with the background
renderer = new THREE.WebGLRenderer({
        antialias: true,
    alpha: true
});
renderer.setSize(screenWidth, screenHeight);
container = document.getElementById('container');
container.appendChild(renderer.domElement); 

// Define the lights for the scene
var light = new THREE.PointLight(0xff00ff);
light.position.set(0, 0, 5);
scene.add(light);
var lightAmb = new THREE.AmbientLight(0x000000);
scene.add(lightAmb);


// Create a circle around the mouse and move it
// The sphere has opacity 0
var mouseGeometry = new THREE.SphereGeometry(1, 0, 1);
var mouseMaterial = new THREE.MeshLambertMaterial({  });
mouseMesh = new THREE.Mesh(mouseGeometry, mouseMaterial);

mouseMesh.position.set(0, 0, 5);
scene.add(mouseMesh);

// When the mouse moves, call the given function
document.addEventListener('mousemove', onMouseMove, false);
}

// Follows the mouse event
function onMouseMove(event) {

// Update the mouse variable
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;

// Make the sphere follow the mouse
var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
vector.unproject( camera );
var dir = vector.sub( camera.position ).normalize();
var distance = - camera.position.z / dir.z;
var pos = camera.position.clone().add( dir.multiplyScalar( distance )     );
mouseMesh.position.copy(pos);

// Make the sphere follow the mouse
//  mouseMesh.position.set(event.clientX, event.clientY, 0);
};

// Animate the elements
function animate() {
requestAnimationFrame(animate);
    render();   
}


// Rendering function
function render() {

// For rendering
renderer.autoClear = false;
renderer.clear();
renderer.render(scene, camera);
};

I tried to simply replace mouseMesh.position.copy(pos); with light.position.copy(pos);, but that just makes the mouseMesh disappear.

Upvotes: 1

Views: 6960

Answers (1)

Paul Graffam
Paul Graffam

Reputation: 2149

The mouseMesh disappeared because its original position is outside the camera view. The other problem is you need to set the light var to be accessible inside the onMouseMove function.

I set up a codepen that shows the point light now following the mouse while the mouseMesh is static:

http://codepen.io/paulmg/pen/yJAwgx?editors=0010

Upvotes: 1

Related Questions