once we have our mouse event poistions normalised to -0.5 - 0.5 , we need to remember that a negative y position makes the camera go “up: therefore we need to invert the y axis

const cursor = {
  x: 0,
  y: 0,
};

window.addEventListener("mousemove", (e) => {
  cursor.x = e.clientX / sizes.width - 0.5;
  cursor.y = -(e.clientY / sizes.height - 0.5);
  console.log("hey", cursor);
});

inside our tick function we can simply update the camera with the cursor values

const tick = () => {
  //Update camera
  camera.position.x = cursor.x * 10;
  camera.position.y = cursor.y * 10;

  // Render
  renderer.render(scene, camera);

  // Call tick again on the next frame
  window.requestAnimationFrame(tick);
};

to keep the position of the item in the center we do this:

camera.position.x = cursor.x * 10;
camera.position.y = cursor.y * 10;
camera.lookAt(mesh.position);

using trigonometry we can make our object spin however many rotations we want. remember that Math.PI will make an object spin 180 degrees.

  camera.position.x = Math.sin(cursor.x * Math.PI * 2) * 3;
  camera.position.z = Math.cos(cursor.x * Math.PI * 2) * 3;
  camera.lookAt(mesh.position);

or just use the built in controls

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

const control = new OrbitControls(camera, canvas);

There is also have smooth flow like control like this

control.enableDamping = true;

but also remember to update the your tick function with

control.update();