Center object on the cursor including zoom

Hi, I’m new to threejs. Following some tutorials I’ve managed to load an object using OBJLoader class and letting it follow my mouse cursor. I see that the local origin of the object is in the center of itself.

The problem is: Depending on the zooming it is following the mouse centered or off-centered. I’m trying to figure it out for few hours now, not getting a correct solution.

function onMouseMove() {
  const { mouseY, mouseX } = projectMouseTo2D();

  if (obj) {
    const axisHelp = new THREE.AxesHelper(10);
    obj.add(axisHelp);
    obj.position.set(mouseX, mouseY, clxHeight);
  }
}

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

  raycaster.setFromCamera(mouse, camera);
  const intersection = new THREE.Vector3();
  raycaster.ray.intersectPlane(plane, intersection);
  return {
    mouseX: intersection.x,
    mouseY: intersection.y,
  };
}
  const canvasContainer = document.getElementById("canvasContainer");
  renderer = new THREE.WebGLRenderer({
    antialias: true,
    preserveDrawingBuffer: true,
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  canvasContainer.appendChild(renderer.domElement);

  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xf0f0f0);

  var groundGrid = createGroundGrid({ num_cells: 5 });
  scene.add(groundGrid);

  planeNew = new THREE.Mesh(
    new THREE.PlaneGeometry(10, 10, 1, 1),
    new THREE.MeshBasicMaterial({ color: 0x555555, wireframe: true }),
  );
  // planeNew.rotation.x = -Math.PI / 2;
  scene.add(planeNew);

  // There is no combined camera anymore; instead use perspective or orthogonal camera
  camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000,
  );
  camera.position.z = 5;

  // lights

  var ambientLight = new THREE.AmbientLight(0x606060);
  scene.add(ambientLight);

  var directionalLight = new THREE.DirectionalLight(0xffffff);
  directionalLight.position.set(1, 0.75, 0.5).normalize();
  scene.add(directionalLight);

  // orbit controls
  controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;
  controls.dampingFactor = 0.05;
  controls.enableZoom = true;
  controls.enablePan = true;
  // controls.maxPolarAngle = Math.PI / 2; // Limit vertical rotation
  // controls.minPolarAngle = Math.PI / 2;
  controls.mouseButtons = {
    LEFT: null,
    MIDDLE: THREE.MOUSE.DOLLY,
    RIGHT: THREE.MOUSE.ROTATE,
  };

  // Create a cube geometry and material
  const boxWidth = 1;
  const boxHeight = 1;
  const boxDepth = 1;
  geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);

  // Setup lighting
  const color = 0xffffff;
  const intensity = 3;
  const light = new THREE.DirectionalLight(color, intensity);
  light.position.set(-1, 2, 4);
  scene.add(light);

  const axesHelper = new THREE.AxesHelper(0.5);
  scene.add(axesHelper);

  plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), -clxHeight);
  const helper = new THREE.PlaneHelper(plane, 5, 0xffff00);
  scene.add(helper);

  // Raycaster stuff init
  raycaster = new THREE.Raycaster();
  mouse = new THREE.Vector2();

  loadCLX();

  // Event listener for mouse movement
  window.addEventListener("mousemove", onMouseMove, false);
  window.addEventListener("resize", onWindowResize, false);
  window.addEventListener("mousedown", onMouseDown, false);

  animate();
}

My first thought was that the origin is off-center which I now confirmed is not the case. Therefore I’m out of thoughts what could be done to handle the problem. Appreciate ideas how to have the object following the mouse regardless of the orbit zoom state.

Yeah orbitcontrols always zooms towards controls.target, and it always points the camera at controls.target.
if you have your worldspace click point… you could disable the zoom/dolly on orbitcontrols and implement the zoom yourself on “wheel” event… by moving the
controls.target (and camera.position) towards the world click point by the wheel amount.

Or you could use “yomotsu camera controls” (check the dolly to cursor checkbox):

https://yomotsu.github.io/camera-controls/examples/focal-offset.html