How to make the camera rotate around a moving object and follow the object?

One of my favorite topics!

Here is a completely different approach that I use to accomplish the same thing.
I link the camera to a 3D object, which acts like a “selfie stick”.
I then link the 3D object to the 3D object of interest so that it is holding the stick
I use mouse input to orbit the camera around the object of interest:

  • mouseX = longitude
  • mouseY = latitude.

Here is some sample code:

// Camera Variables
let CamDst = 500;	// distance from object you are looking at
let CamLat = 30;	// vertical position of camera (+/-90 degrees) 30 = up
let CamLon = 0;		// horizontal position of camera (0-360 degrees) 0 = straight ahead
let LatMax = 90;	// limit input value to 90 degrees, so you don't go "upside down"
let LatMin = -90;	// Same for down	
// Create Camera and Holder
const camera = new THREE.PerspectiveCamera(45, width/height, 1, 15000);
	camera.rotation.order = "YXZ";
const camobj = new THREE.Object3D();	// This is like a camera "selfie stick" that holds the camera
	camobj.rotation.order = "YXZ";	// You rotate the "stick" to position the camera in space
	camobj.add(camera);		// Attach the camera to the stick
	camera.position.z = -CamDst;	// Length of "stick"
	camera.rotation.y = 180*DegRad;	// Camera looks towards the object holding the "stick"
// Object of Interest (you can add the mesh later)
const ctrobj = new THREE.Object3D();	// Create object
	ctrobj.rotation.order = "YXZ";
	ctrobj.add(camobj);		// Attach camera "stick" to the object
	scene.add(ctrobj);

// I use mouse input to rotate the lat/lon of the "stick", which causes the camera to orbit the object:
// * up/down changes latitude (limit to +/-90 degrees)
// * left/right changes longitude
// * mouse wheel changes distance from object
// I call the function below with each frame (but it is so small, you can just include it in your code)
function moveCamera() {
	camera.position.z = -CamDst;	// in case, change distance from object
	camobj.rotation.x = Mod360(CamLat)*DegRad;
	camobj.rotation.y = Mod360(CamLon+180)*DegRad;
}

Note: that you can also “bank” the camera using rotation.z - something you can’t do with LookAt
Also, note: I am using 3Dobjects, rather than just a mesh because you can link to a 3Dobject.

This is a pretty flexible setup:

  1. You can easily look outwards (just make camera.roation.y = 0)
  2. You can attach the camera holder to different objects of interest (e.g. different planets rotating the sun) to look at them.
  3. You can use linked objects to change the orientation of your axis.