Cannot change colour when hover over

Hello. I want to change colour the colour of the mesh, when the mouse hovers over.
And when the mouse leaves, the mesh should return to its original colour.

This is the code i wrote:

<!DOCTYPE html>

<html>

<head>
    <title>Example 01.02 - First Scene</title>
    <script type="text/javascript" src="../libs/three.js"></script>
    <style>
        body {
            /* set margin to 0 and overflow to hidden, to go fullscreen */
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>

<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>

<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">


    window.onload = init();
    animate(); //calling function that does all the rendering 
    

    //GLOBAL VARS
    var scene, camera, renderer;
    var raycaster, mouse;
    var INTERSECTED;

    // once everything is loaded, we run our Three.js stuff.
    function init() {

        // create a scene, that will hold all our elements such as objects, cameras and lights.
        scene = new THREE.Scene();

        //SET CAMERA
        camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
        camera.position.z = 5;

        // create a render and set the size
        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setClearColor("#e5e5e5"); //background color
        renderer.setSize(window.innerWidth,window.innerHeight); //size of renderer

        //bind rendered to the dom element
        document.getElementById("WebGL-output").appendChild(renderer.domElement);  

       
        //RAYCASTER
        raycaster = new THREE.Raycaster();
        mouse = new THREE.Vector2();

        
        // create a cube
        var cubeGeometry = new THREE.BoxGeometry(20, 0.00001, 20);
        var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xffff00 }); //0xF7F7F7 = gray
        var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

        // position the cube
        cube.position.x = 0;
        cube.position.y = 3;
        cube.position.z = 0;
        scene.add(cube);
        

        //ADDING LIGHTS
        var ambientLight = new THREE.AmbientLight(0x0c0c0c);
        scene.add(ambientLight);
        var spotLight = new THREE.SpotLight(0xffffff);
        spotLight.position.set(-40, 60, -10);
        spotLight.castShadow = true;
        scene.add(spotLight);

       
        // position and point the camera to the center of the scene
        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 30;
        camera.lookAt(scene.position);


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

    function onDocumentMouseMove(event)
    {
      // the following line would stop any other event handler from firing
      // (such as the mouse's TrackballControls)
       event.preventDefault();

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

      
    }

    function animate()
    {
      render();
    }

    


    function render() 
    {

        // update the picking ray with the camera and mouse position
        raycaster.setFromCamera( mouse, camera );

        // calculate objects intersecting the picking ray
        var intersects = raycaster.intersectObjects( scene.children );



        for ( var i = 0; i < intersects.length; i++ )
        {
            intersects[ i ].object.material.color.set( 0xff0000 );
        }

        requestAnimationFrame(animate); //pauses when user switches tab
        renderer.render(scene, camera);
    }


</script>
</body>
</html>

The mesh should start with a colour and when the mouse hovers over, it should change.
However, with my code, the mesh starts as the colour it should change to, and there is no interaction with the mouse.

The colour is just permanent

Updated code: https://jsfiddle.net/rpb2n7k8/

  • You need to reset the color if no intersection occurs.
  • It’s recommended to set the default value of mouse to something else than (0,0). Otherwise the app assume the mouse is in the screen’s center and this will immediately lead to an intersection.

Thanks a ton!
But your version worked, even though you didn’t set the mouse coordinates.
How is that?

Can you please explain in more detail what you mean by that? I’m afraid I don’t understand^^.

Is this your question, @n13?

You said this, yet in your code that works, you didn’t set the coordinates to something other than (0,0). Yet your code works.
How is that possible?

Yes it is. Though, from Mugen’s answer i got it to working.
I used mouse = new THREE.Vector2(); , yet everything worked.

I’m afraid that’s not correct. I initialize mouse like so:

mouse = new THREE.Vector2(1,1);

and the onDocumentMouseMove() handler updates mouse.

2 Likes

Oh ok.
For some reason i used this
mouse = new THREE.Vector2();
and still it worked with your implementation of render().
Still, i will use (1,1) from now on.

Thanks!

If i want to add extra functionaluty when someone clicks the mesh…
Do i have to provide another event listener like this:
document.addEventListener('click'....)
with my own function?
Because the onDocumentMouseMove() function for the first event i already got (mouseMove) just gets the mouse data, and all the collision logic is handled ar render()…
So do i need an extra eventListener, or just add the logic in render()?

@Mugen87 but this code works only for one cube. if you add more then one cube this code change color only when the mouse hover on first cube. I want when i hover on a perticular cube the cube size should increase. can you help me. thanks in advance?