gjjr
gjjr

Reputation: 569

Prevent click when dragging three.js

I have a GLTF model in Three.js with objects inside the model, when the user clicks an object the camera zooms in to focus on the object.

I am trying to prevent clicking when the user drags, as currently if the user clicks and object and drags, when they release the mouse button, a click is triggered and the camera zooms into the object. I have tried to setup a "dragged" variable with nested if statement to fix this as you can see in my code below, but its not working. Does anyone know how to fix this issue?

var mesh=[];

const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2()

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

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

    raycaster.setFromCamera( mouse, camera );

    var intersects = raycaster.intersectObjects( scene.children, true );

    var dragged = false
    window.addEventListener('mousedown', function () { dragged = false })
    window.addEventListener('mousemove', function () { dragged = true })
    window.addEventListener('mouseup', function() {
        if (dragged == true) { return }
        //Click Tree006 to focus
    if ( intersects.length > 0 && intersects[0].object.name==="Tree006") {
        var object = intersects[0].object;
        zoomInTimeline(mesh["Tree006"].position.x, mesh["Tree006"].position.y, mesh["Tree006"].position.z, 5);

    console.log( 'Intersection:', intersects[ 0 ] );
    }

    //Click anywhere outside of object to leave focus
    if ( intersects.length > 0 && intersects[0].object.name!=="Tree006") {
        var object = intersects[0].object;
        gsap.to( camera.position, {
            duration: 1, // seconds
            x: 6,
            y: 4,
            z: 4,
            onUpdate: function() {
                controls.enabled = true;
                // controls.enableRotate = true;
                
            }
        } );
    }

    //Click object to focus
    if ( intersects.length > 0 && intersects[0].object.name==="Tree001") {
        var object = intersects[0].object;
        zoomInTimeline(mesh["Tree001"].position.x, mesh["Tree001"].position.y, mesh["Tree001"].position.z, 5);
    
    console.log( 'Intersection:', intersects[ 0 ] );
    }

    //Click anywhere outside of object to leave focus
    if ( intersects.length > 0 && intersects[0].object.name!=="Tree001") {
        var object = intersects[0].object;
        gsap.to( camera.position, {
            duration: 1, // seconds
            x: 6,
            y: 4,
            z: 4,
            onUpdate: function() {
                controls.enabled = true;
                // controls.enableRotate = true;
                
            }
        } );
    }
})
}

Upvotes: 0

Views: 982

Answers (1)

M -
M -

Reputation: 28487

Just think of it sequentially:

  1. User clicks down.
  2. User moves mouse while holding down.
  3. If user releases without moving, it's a click. If user releases after moving, it's a drag.
var mDragging = false;
var mDown = false;

window.addEventListener('mousedown', function () {
    mDown = true;
});
window.addEventListener('mousemove', function () {
    if(mDown) {
        mDragging = true;
    }
});
window.addEventListener('mouseup', function() {
    // If not dragging, then it's a click!
    if(mDragging === false) {
        // Perform all your click calculations here
    }

    // Reset variables
    mDown = false;
    mDragging = false;
});

Upvotes: 2

Related Questions