2

My problem is the following : The mousehover actions works on the cubes even if the mouse is not directly over the cubes, it works if it is on an Y axis over or under the cubes, out of the scene. Can someone explain me why and how to fix it?

 <!DOCTYPE html>
    <html lang="fr" xml:lang="fr" xmlns="http://www.w3.org/1999/xhtml">
    <head>



     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>        

    <script src="lib/Three.js" type="text/javascript"></script>

    <script src="lib/Detector.js"></script>
    <script src="lib/stats.min.js" type="text/javascript"></script>
    <script src="lib/THREEx/THREEx.WindowResize.js"></script>
    <script src="lib/THREEx/THREEx.FUllScreen.js"></script>
    <script src="lib/TrackballControls.js"></script>

      <style type="text/css">
      body
    {
        color: #ffffff;
        text-align:center;
        background-color:  gray;
        margin: 0px;
    }
    #center
    {
        color: #fff;
        position: absolute;
        top: 50px; width: 100%;
        padding: 5px;
        z-index:100;
    }

    #center h1
    {

        font-size:60px;
    }

    #container
    {
        position:absolute;
        bottom:0;
    }

      </style>

    </head>

    <body>

    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <div id="container"></div>


     </body>

     <script>
    // MAIN

    console.log("Main.js");
    if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

    // global variables

    var container, scene, camera, renderer, stats, controls;

    // custom variables 

    var t = THREE;
    var cube;

    // to keep track of the mouse position
    var projector, INTERSECTED, mouse = { x: 0, y: 0 },

    // an array to store our particles in
    particles = [];

    init();
    animate();

    function init()
    {


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

        // camera
        var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
        var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
        camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
        scene.add(camera);
        camera.position.set(0,0,800);
        camera.lookAt(scene.position);

        // renderer
        renderer = new THREE.CanvasRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );

        // container
        container = document.getElementById('container');
        container.appendChild( renderer.domElement );

        // stats
        stats = new Stats();
        stats.domElement.style.position = 'absolute';
        stats.domElement.style.bottom = '0px';
        stats.domElement.style.zIndex = 100;
        container.appendChild( stats.domElement );

        // events 
        THREEx.WindowResize(renderer, camera);
        THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) });

        // initialize object to perform world/screen calculations
        projector = new THREE.Projector();

        // CUSTOM

        // Cubes

        x = window.innerWidth / 5;
        y =  window.innerHeight / 10;
        console.log(window.innerWidth);
        console.log(window.innerHeight);
        var geometry = new t.CubeGeometry(125,125,125);
        var material = new t.MeshBasicMaterial({color:0xCCCCCC});
        cube = new t.Mesh(geometry, material);
        cube.name = "cube";

        scene.add(cube);
        cube.position.set(-x,-y,0);

        x = window.innerWidth;
        y =  window.innerHeight / 10;

        var geometry2 = new t.CubeGeometry(125,125,125);
        var material2 = new t.MeshBasicMaterial({color:0xCCCCCC});
        cube2 = new t.Mesh(geometry2, material2);
        scene.add(cube2);

        cube2.name = "cube2";
        cube2.position.set(0,-y,0);


        x = window.innerWidth / 5;
        y =  window.innerHeight / 10;

        var geometry3 = new t.CubeGeometry(125,125,125);
        var material3 = new t.MeshBasicMaterial({color:0xCCCCCC});
        cube3 = new t.Mesh(geometry3, material3);
        cube3.name = "cube3";

        scene.add(cube3);
        cube3.position.set(x,-y,0);

        // particles

        makeParticles(); 


    // Mouse events
    document.addEventListener( 'mousemove', onMouseMove, false ); 
    document.addEventListener( 'mousedown', onMouseDown, false ); 


    }


    // called when the mouse moves
    function onMouseMove( event ) 
    {
    // store the mouseX and mouseY position 
    mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
    }

    function onMouseDown( event ) 
    {
        event.preventDefault();

        var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
        projector.unprojectVector( vector, camera );
        var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );

        var intersects = ray.intersectObjects( scene.children );

        if ( intersects.length > 0 )
        {
            console.log(INTERSECTED.name);
            if(INTERSECTED.name == "cube")
            {
                page("real");
            }
        }
    }

    function animate() 
    {
        cube.rotation.y +=0.005;
        cube.rotation.x -=0.005;
        cube2.rotation.y +=0.005;
        cube2.rotation.x -=0.005;
        cube3.rotation.y +=0.005;
        cube3.rotation.x -=0.005;
        //textMesh.rotation.y +=0.005;

        requestAnimationFrame( animate );
        render();   
        update();   
    }

                    // creates a random field of Particle objects

    function makeParticles() 
    { 

    var particle, material; 

        // we're gonna move from z position -1000 (far away) 
        // to 1000 (where the camera is) and add a random particle at every pos. 
        for ( var zpos= -1000; zpos < 1000; zpos+=20 ) 
        {

        // we make a particle material and pass through the 
        // colour and custom particle render function we defined. 
        material = new THREE.ParticleCanvasMaterial( {  program: particleRender } );
        // make the particle
        particle = new THREE.Particle(material);

        // give it a random x and y position between -500 and 500
        particle.position.x = Math.random() * 1000 - 500;
        particle.position.y = Math.random() * 1000 - 500;

        // set its z position
        particle.position.z = zpos;

        // scale it up a bit
        particle.scale.x = particle.scale.y = 10;

        // add it to the scene
        scene.add( particle );

        // and to the array of particles. 
        particles.push(particle); 
        }
    }

    // there isn't a built in circle particle renderer 
    // so we have to define our own. 

    function particleRender( context ) 
    {

    // we get passed a reference to the canvas context
    context.beginPath();
    // and we just have to draw our shape at 0,0 - in this
    // case an arc from 0 to 2Pi radians or 360º - a full circle!
    context.arc( 0, 0, 0.2, 2,  Math.PI * 4, true );
    context.fillStyle = "white";
    context.fill();
    };

        // moves all the particles dependent on mouse position

    function updateParticles() 
    { 

        // iterate through every particle
        for(var i=0; i<particles.length; i++) 
        {

        particle = particles[i]; 

        // and move it forward dependent on the mouseY position. 
        particle.position.z +=  250 * 0.02;

        // if the particle is too close move it to the back
        if(particle.position.z>1000) particle.position.z-=2000; 

        }

    }

    function render()
    {
    renderer.render( scene, camera );
    }

    function update()
    {
    updateParticles();
    stats.update();


        // find intersections

        // create a Ray with origin at the mouse position
        //   and direction into the scene (camera direction)
        var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
        projector.unprojectVector( vector, camera );
        var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );

        // create an array containing all objects in the scene with which the ray intersects
        var intersects = ray.intersectObjects( scene.children );

        // INTERSECTED = the object in the scene currently closest to the camera 
        //      and intersected by the Ray projected from the mouse position    

        // if there is one (or more) intersections
        if ( intersects.length > 0 )
        {
            // if the closest object intersected is not the currently stored intersection object
            if ( intersects[ 0 ].object != INTERSECTED) 
            {
                // restore previous intersection object (if it exists) to its original scale
                if ( INTERSECTED )  
                {
                    INTERSECTED.scale.x = INTERSECTED.currentscale.x;
                    INTERSECTED.scale.y = INTERSECTED.currentscale.y;
                    INTERSECTED.scale.z = INTERSECTED.currentscale.z;
                }
                // store reference to closest object as current intersection object
                INTERSECTED = intersects[ 0 ].object;
                // store scale of closest object (for later restoration)
                scalex = INTERSECTED.scale.x;
                scaley = INTERSECTED.scale.y;
                scalez = INTERSECTED.scale.z;

                INTERSECTED.currentscale = { x : scalex , y : scaley, z : scalez };
                // set a new scale for closest object
                INTERSECTED.scale.x = INTERSECTED.scale.y = INTERSECTED.scale.z = 1.5;


            }
        } 

        else // there are no intersections
        {
            // restore previous intersection object (if it exists) to its original scale
            if ( INTERSECTED ) 
            {
                INTERSECTED.scale.x = INTERSECTED.currentscale.x;
                INTERSECTED.scale.y = INTERSECTED.currentscale.y;
                INTERSECTED.scale.z = INTERSECTED.currentscale.z;
            }

            // remove previous intersection object reference
            //     by setting current intersection object to "nothing"
            INTERSECTED = null;
        }

    }



    // Pour charger une page dynamiquement
        function page(page){
        $("body").animate({opacity:0},1000, function(){
        $("body").empty();
        $("body").load(page +'.html');
        $("body").animate({opacity:1},1000, function(){

                });
            });
    }


     </script>






    </html>
1
  • 3
    You are much more likely to get help if you provide a simple, live example demonstrating your issue. Make it easy for others to help you. Commented Feb 21, 2013 at 16:03

1 Answer 1

1

Is there an offset between the window top left corner and the canvas top left corner? If so, you have to calculate the offset (top and left) and subtract the values from the event.client values.

Try this :

// now get the space between top left browser window corner
var absoluteOffsetLeft = 0;
var absoluteOffsetTop = 0;
var obj = <your HTML object containing the canvas>;

// taken from http://www.quirksmode.org/js/findpos.html
if (obj.offsetParent) {
    do {
        absoluteOffsetLeft += obj.offsetLeft;
        absoluteOffsetTop += obj.offsetTop;
    } while (obj = obj.offsetParent);
} else {
    console.log("Method offsetParent not supported");
}

// YOUR mouse move event handler - also take the innerWidth and Height from the canvas
function onMouseMove( event ) {
    // store the mouseX and mouseY position 
    mouse.x = ( (event.clientX - absoluteOffsetLeft) / canvas.innerWidth ) * 2 - 1;
    mouse.y = - ( (event.clientY - absoluteOffsetTop) / canvas.innerHeight ) * 2 + 1;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.