Model position jumping during interaction

Hi there :wave:

I’ve got a model set up in a react (gatsby) component, and am having an issue where the models position on init is different than the position during interactivity. The effect being that when the canvas is engaged with - the model jumps up to a new position.

I’m not sure what’s causing this - and am hoping that someone might be able to see where I’ve gone wrong.

Here is a link to a mockup on codesandbox

const ThreeJS = () => {
  const containerRef = useRef(null);

  useEffect(() => {
    if (!containerRef.current) return;

    /*------------------------------
    # Container and Camera Setup
    ------------------------------*/
    const container = containerRef.current;
    const camera = new THREE.PerspectiveCamera(
      45,
      window.innerWidth / window.innerHeight,
      1,
      50
    );
    camera.position.z = 10;

    /*------------------------------
    # Scene Setup
    ------------------------------*/
    const scene = new THREE.Scene();

    /*------------------------------
    # Lighting Setup
    ------------------------------*/
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);

    const directionalLight1 = new THREE.DirectionalLight(0xffffff, 0.5);
    directionalLight1.position.set(3, 3, 3);
    scene.add(directionalLight1);

    const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.5);
    directionalLight2.position.set(-3, 3, 3);
    scene.add(directionalLight2);

    /*------------------------------
    # Renderer Setup
    ------------------------------*/
    const renderer = new THREE.WebGLRenderer({ alpha: true });
    renderer.setSize(380, 380);
    container.appendChild(renderer.domElement);

    const render = () => {
      renderer.render(scene, camera);
    };

    /*------------------------------
    # Controls Setup
    ------------------------------*/
    let controls;

    const initControls = (target) => {
      controls = new TrackballControls(camera, container);
      controls.addEventListener("change", render);
      controls.noPan = true;
      controls.minDistance = 5;
      controls.maxDistance = 15;
      controls.target = target;
    };

    /*------------------------------
    # Model Loading
    ------------------------------*/
    const loader = new GLTFLoader();
    renderer.gammaOutput = true;
    renderer.gammaFactor = 2.2;

    loader.load(
      model,
      (glb) => {
        const object = glb.scene.children[0];
        object.position.set(-0.02, -0.75, 2);
        object.rotation.set(90, 0.25, -0.5);
        scene.add(object);

        const boundingBox = new THREE.Box3();
        boundingBox.setFromObject(object);
        const center = new THREE.Vector3();
        boundingBox.getCenter(center);

        initControls(center);
        render();
      },
      undefined,
      (error) => {
        console.error(error);
      }
    );

    /*------------------------------
    # Animation Loop
    ------------------------------*/
    const animate = () => {
      requestAnimationFrame(animate);
      if (controls) {
        controls.update();
      }
    };

    animate();

    /*------------------------------
    # Cleanup Function
    ------------------------------*/
    return () => {
      if (controls) {
        controls.dispose();
      }
      renderer.dispose();
      container.removeChild(renderer.domElement);
    };
  }, []);

  return (
    <div
      ref={containerRef}
      style={{
        backgroundColor: "rgba(0, 0, 255, 0.205)",
      }}
    />
  );
};

export default ThreeJS;

Hi!
I would try this:

    const initControls = (target) => {
      controls = new TrackballControls(camera, container);
      controls.addEventListener("change", render);
      controls.noPan = true;
      controls.minDistance = 5;
      controls.maxDistance = 15;
      controls.target = target;
      controls.update(); // add this line
    };

You instantiate controls, then set its target, but camera still looks in (0, 0, -1) direction, and it still looks there till you click and move your mouse, since that moment controls start to take target in count. To force the controls to use that manually set target, call .update() when you change some settings right after instantiation.