Reverting controls['target'] back to (0, 0, 0) after a tween

Not sure if this is similar to this question here:

Basically, I am tweening my camera’s position to lock onto an Object3D mesh. During the tween update, I do this:

controls['target'].copy(object3D['position']);

At the end of the tween, the origin is basically that object3D I locked onto and the camera rotates around that object3D. How would I set my control’s target back to (0, 0, 0) without having the camera look like it is snapping back to the position before the tween started? I tried doing this but the screen turned all black after I moved my mouse:

controls['target'].set({ 'x': 0, 'y': 0, 'z': 0 });

I’d like to see a smooth camera movement away (ie: no snapping back into the original pre-tween position) from that target object3D and the rotation point for the OrbitControls to be (0, 0, 0) again. Thank you.

I should add that I could remove the tween updateCallback and the center point will be good, however it still snaps the moment I move the mouse after the tween.

One weird thing I notice is my camera[‘position’] gives the same Vector3 data values during the entire tween in the onUpdate callback when it is clear that the camera is moving.

@Superman

Will this resolve the all-black issue?

controls['target'].set(0,0,0);

– Pavel

I removed the tween update callback and dropped the controls[‘target’] code so the center of rotation is ok still at the end of the tween. There is just that weird snapping when I move the the PerspectiveCamera. Maybe I need to run some sort of update() function but I tried camera.updateProjectionMatrix() but that did not fix the snapping issue.

I tried this also camera[‘position’].copy(camera[‘position’]); but that did nothing.

@Superman

To be honest, I’m not sure I understand the issue. If you use a tween to move smoothly the camera target to another object … and you want to move it back to (0,0,0)… that could be done by another tween, couldn’t it? Here is my attempt:

– Pavel


Here is my demo. See it jump back into the pre-tween position. Weird really. I see that yours works fine. eeek…

I’m using gsap by the way. Not sure if that matters.

Again, during the onUpdate, my camera[‘position’] console log output remains the same all along even though the camera is clearly panning over to the clicked object. I would have expected the value to change during the updates.

@Superman

Here is the part of my code that handles the target. You can see, I use a tween both to move to another target and to return to (0,0,0).

<button onclick="retarget(yellowCube.position);">Orbit yellow</button>
<button onclick="retarget(scene.position);">Orbit (0,0,0)</button>
<button onclick="retarget(redCube.position);">Orbit red</button>
		
<script>
:
function drawFrame()
{
	:
	TWEEN.update();
	controls.update();			
	renderer.render( scene, camera );
}
			
function retarget( newTarget )
{
	new TWEEN.Tween( controls.target )
		.to( newTarget, 500 )
		.start();
}
</script>

– Pavel

I’m trying it with the ThreeJS Tween now. I get the same jumping problem.

const TWEEN_DATA = { 'x': TARGET_QUATERNION['x'], 'y': TARGET_QUATERNION['y'], 'z': TARGET_QUATERNION['z'], 'w': TARGET_QUATERNION['w'] };

new TWEEN.Tween(camera.quaternion).to(TWEEN_DATA, 1000).start();

@Superman

Most likely the issue comes from part of the code, that you do not show. I hope that somebody can give you a better suggestion than me.

– Pavel

PS. I’m not sure whether changing directly the camera is good. OrbitControls also changes the camera, and it will overwrite your changes. See in my example, I do not work with the camera, but only with the controls.

1 Like

Here is a tweenjs example of changing the orbit controls target.
What prevents the jump when the tween finishes in this example, is the controls.update() in the animation loop.
Using tween.js with OrbitControls
image

Pres the <> in the working example for the inline vanillajs code using import maps.

I shall give that a try in a bit. Note that there is also no jumping for me if I update the controls.target point to the Object3D point at the end of the tween. But if I decided not to update it, it jumps. I am also tweening the camera.quaternion data/object if that matters at all.

You may be correct about updating the camera causing problems. I shall do a test and see if that is the cause and find an alternative object to update.

An observation I should mention is that is controls.update() is executed, I revert back to the position pre-tween and tweening the camera.quaternion will not “completely work” (ie: seems to struggle and fight some force to tween and reset back and forth. Could be what Pavel mentionned that OrbitControls updates the camera also…). Again, I am tweening the camera.quaternion object. I may have to put the controls.update() call back into the animation frame callback or the OrbitControls auto rotate will not update correctly. Seems like the tweening of the camera may be the issue. Testing further to be sure.

It’s confirmed, it is the tweening of the camera.quaternion object (or camera) that is the problem.

I removed controls.update() from the animate() function otherwise the tweening of the camera will not work as it keeps resetting with the controls.update() call.

I changed the tween to this:

  new TWEEN.Tween(camera.quaternion)
      .to(
          {
              x: 0.2,
              y: 0.3,
              z: 0.1,
          },
          500
      )
      .easing(TWEEN.Easing.Cubic.Out)                        
      .start()

What you get after you pick a new point is a jump back to the initial pre-tween location.

There must be a solution to this. Like updating the camera somehow or maybe the controls to reflect the new and final position.

I struggle to image what you are trying to achieve.
Is it anything like one of these examples. They all are all different in some way.

Example 1 : Glasses - Three.js Tutorials
Example 2 : Annotations - Three.js Tutorials
Example 3 : https://fcs.sbcode.net/

If not, is there something you’ve seen on the internet that shows what you want?

1 Like

ok, here is the required setup. You have an OrbitControls that will auto rotate. That means you will need controls.update() inside your animate() recursive function.

The goal here is to be able to click a point (or Object3D) and have our camera look at that point. That means that point we clicked will go towards the center of the screen. Important that we are not trying to move towards that point (ie: moving right at that point distance wise). So basically, we will need to play with the angles/quaternion.

Now, for those 3 examples, the first 2 works because the controls.target changes each time we click on one of those numbered points. That is the expected behaviour and that’s what I’m getting also.

The goal here is how do we click on those numbered points in the examples, and our camera look at the point in question like in the example, but then, be able to move our camera away from that point using our original (0, 0, 0) controls.target point of rotation.

What’s thinking of doing is place a code to tell the animate() function to not execute controls.update() while I am tweening my camera.quaternion towards the target point as the OrbitControls will cancel out that tween. At the end, I need to somehow find a way to update my camera so that it does not jump back to the initial pre-tween point when controls.update() is re-enabled. The question here is how. I don’t really want to modify OrbitControls.js as that would make it non-standard. I wonder which part of the update() code contains the original pre-tween rotation/quaternion and needs to be updated…

I still don’t know what you want.
Create something in jsfiddle/codepen/codesandbox that shows exactly the problem.
Or link an example somewhere on the internet that shows exactly what you want it.

Is this what you want?

1 Like