Rotate & Translate Camera to Focus on Object

I’m trying to focus on a Mesh object when it is clicked. I currently have it working except for one slight issue.

Consider the following example, with the scene set up as so, with the first (largest) sphere at the centre:

If I click the green sphere, focus successfully switches to it:

So all seems well.

However, consider the same scene setup, but the camera has been rotated (using OrbitControls):

Clicking on the green sphere still shifts focus (even if my screenshot doesn’t make it obvious), but it is occluded by the objects in front of it:

How can I use the position of the object to also rotate the camera (not the objects) so the clicked item is always in view? So I can go from this:

To this:

I currently have code to test whether objects are blocking a given object from the camera (using raycasters) but I’m not sure how to use this to determine the angle to rotate the camera by.

Additionally, when the object is clicked, I’d like to zoom in as much as possible so the sphere takes up the majority of the screen, i.e., something like this:

But I’m not sure how to calculate the amount to zoom in, mathematically speaking.

The following approach should solve the issue: Need help with gsap camera and OrbitControls animations - #2 by Mugen87

There is also a live example that demonstrates the solution by animating a camera with GSAP.

BTW: The title of your post is not correct. You don’t want to just rotate the camera. You actually need tranlate + rotate similar to an orbital movement.

One simple approach that might help is to determine the view direction of your camera first. If the target object is occluded, you might want to negate the view direction and then offset the camera from the target’s position. In this way you basically mirror the camera (or change sides).

Hi @Mugen87, thanks for the reply.

I had some gsap code already and tried to use your example to work with my orbitControls but came across some difficulty. The camera.lookAt method seems to have no effect - if I don’t update the, the camera stays looking at the origin. However, if I update the controls target instead, the animation jumps initially and the camera zooms in too much.

The zooming issue is solved by making the final camera position centre.z + size.z but the animation still skips initially. I don’t get this problem in the fiddle you sent, even if I modify it.

I’m using troisjs so the problem must clearly be in my components, I’ll try to setup a minimal fiddle to demonstrate.


I managed to fix it by manually updating both the controls target and the camera position. Although, I’m not sure why I couldn’t just follow your example by just updating the camera position.

Here’s the sandbox link

As for the rotation, I can test for occlusions currently. My idea is to find a rotation such that there is no occlusion and rotate the camera by that angle (and then zoom). I’m not sure how to do this without actually having to rotate the camera. Maybe keep rotating the camera until there is no occlusion (or one full rotation complete)?