简体   繁体   中英

Three.js toggle object position with mouse click

I'm trying to recreate the click effect of this site , (enter and scroll in to see the magic). When you click on a pic, it moves front and center in front of the camera. And when you click it again, it goes back to it's original position. I'm having trouble bringing objects back to their original position because those coords get lost when an the object moves.

I got it kinda working by storing the Vector3 in a global array and recalling those positions, but the way I have it set up, it breaks if the camera is moved(the camera likes to move by itself for some reason).

Here's what I tried.

var coordArray = [new THREE.Vector3(0, 0, 0)];
var raycaster = new THREE.Raycaster();  // raycaster for click events
var mouse = new THREE.Vector2();  //mouse coords
function onMouseClick(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) //return array based on objects that interact with it
    for(var i=0; i<intersects.length; i++){ 
        this.tl = new TimelineMax();
        originalCoords = new THREE.Vector3(intersects[0].object.position.x, intersects[0].object.position.y, intersects[0].object.position.z);
        coordArray.push(originalCoords);

        if(intersects[0].object.position.z != camera.position.z - 5)
            this.tl.to(intersects[0].object.position, 1, {x: 0, y: 0, z: camera.position.z - 5, ease: Expo.easeOut});
        else
            this.tl.to(intersects[0].object.position, 1, {x: coordArray[coordArray.length-2].x, y: coordArray[coordArray.length-2].y, z: coordArray[coordArray.length-2].z, ease: Expo.easeOut});           
    }
}

Any help would be greatly appreciated. And I fully expect to be flamed for my ignorance as well as a host of other random minutia. The answer is worth the embarrassment :p

I was able to get the effect I wanted by storing the cube's initial position as it's name.

    cube.position.set(-10, 5, -10);
    cube.name = "-10 5 -10";

Then in my click event split the name at the space and use the indexes as coordinates

var raycaster = new THREE.Raycaster();  // raycaster for click events
var mouse = new THREE.Vector2();  //mouse coords
function onMouseClick(event){
    event.preventDefault();

    // Get position of the mouse on click
    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) //return array based on objects that interact with it
    for(var i=0; i<intersects.length; i++){ 
        this.tl = new TimelineMax();

        var initialPosition = intersects[0].object.name.split(" ");

        if(intersects[0].object.position.z != camera.position.z - 5){
            this.tl.to(intersects[0].object.position, 1, {x: 0, y: 0, z: camera.position.z - 5, ease: Expo.easeOut});
        }
        else{
            this.tl.to(intersects[0].object.position, 2, {x: initialPosition[0], y: initialPosition[1], z: initialPosition[2], ease: Expo.easeOut});
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM