Search code examples
three.jsgsap

Three.js meshGroup once moved can't move back


I am trying to move a meshGroup to the right, and then move it back. But once the meshGroup is moved it can not move again, like only move to the right or left it works fine, but once it is moved it won't move back to the left or right. I am using meshGroup.position.x to do the movement, here is the code:

const moveMeshRight = (mainMeshGroup:Group) => {
            gsap.to(mainMeshGroup.position, {
                duration: 0.5,
                x: 115,
                onUpdate:()=>{
                    console.log(mainMeshGroup.position)
                }
            })
            gsap.to(mainCamera.position,{
                duration:0.5,
                z:500
            })
        }

        const moveMeshLeft = (mainMeshGroup:Group) => {
            gsap.to(mainMeshGroup.position, {
                duration: 0.5,
                x:-115,
                onUpdate:()=>{
                console.log(mainMeshGroup.position)
            }
            })
        }

They are used in two click event:

<div style={{ position: "absolute" }}>
        {drawer?null:display1Fade}

        {drawer?null:<Button style={{
            position: 'absolute',
            backgroundColor: 'black',
            height: '60px',
            marginLeft: '16px',
            marginTop: '16px',
            zIndex: 1
        }} onClick={() => {
            setDrawer(true);
            //mainMeshGroup.position.x+=50
            moveMeshRight(mainMeshGroup)
        }}>

        </Button>}
      <div className={drawer?classes.displayButtonDivMove:classes.displayButtonDiv}>
          {<div className={detail?classes.displayButtonExpand1:classes.displayButton}
                onClick={()=>{
                    setDisplay1(true);
                    setDrawer(false);
                    moveMeshLeft(mainMeshGroup)
                }}>
              Display Type 1</div>}
          {<div style={{marginLeft: '10px'}} className={detail?classes.displayButtonExpand2:classes.displayButton} onClick={()=>{setDisplay1(false);setDrawer(false)}}>Display Type 2</div>}
      </div>


Solution

  • Here is a complete example that demonstrate simple left/right animations controlled via two buttons:

    let camera, scene, renderer;
    
    let group;
    
    init();
    animate();
    
    function init() {
    
      camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
      camera.position.z = 4;
    
      scene = new THREE.Scene();
    
      group = new THREE.Group();
      scene.add(group);
    
      const geometry = new THREE.BoxGeometry();
      const material = new THREE.MeshNormalMaterial();
    
      const mesh = new THREE.Mesh(geometry, material);
      group.add(mesh);
    
      renderer = new THREE.WebGLRenderer({
        antialias: true
      });
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(renderer.domElement);
    
      const btnLeft = document.getElementById('btn-left');
      btnLeft.addEventListener('pointerdown', moveLeft);
    
      const btnRight = document.getElementById('btn-right');
      btnRight.addEventListener('pointerdown', moveRight);
    
    }
    
    function animate() {
    
      requestAnimationFrame(animate);
      renderer.render(scene, camera);
    
    }
    
    function moveLeft() {
    
      gsap.to(group.position, {
        duration: 1,
        x: -1
      });
    
    }
    
    function moveRight() {
    
      gsap.to(group.position, {
        duration: 1,
        x: 1
      });
    
    }
    body {
        margin: 0px;
    }
    div {
      position: absolute;
      width: 100%;
      text-align: center;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.0/gsap.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.130.1/build/three.min.js"></script>
    <div>
      <button id="btn-left">
        Left
      </button>
      <button id="btn-right">
        Right
      </button>
    </div>