我正在用three.js做一个navigation test,带有点击导航功能。
点击机制非常简单:raycaster确定用户单击的平面中的点,我将相机移动到那里gsap
:
const move_cam = () => {
const new_pos = { ...marker.position };
gsap.to(camera.position, {
duration: 2,
x: new_pos.x,
z: new_pos.z,
onComplete: () => {
}
});
};
这样做的问题是,当与OrbitControls沿着使用时,摄影机移动时总是指向同一个地方:
原因是OrbitControls为相机提供了一个目标,让它继续观察,允许它“环绕”。
我的第一次尝试只是在相机移动期间使用controls.enabled= false
禁用OrbitControls,并在事后使用gsap
的回调函数onComplete()
重新启用它,但它不起作用,因为controls.enabled= false
仅禁用与用户的交互,但它不会阻止相机查看其目标。
我还考虑过通过在动画循环中添加一个条件来防止OrbitControls在移动过程中影响摄影机:
if (!camera_is_moving) {
controls.update();
}
但动画一结束,摄影机就会返回到目标。
作为最后一次重新排序,我决定将相机到其目标的距离存储在一个名为offset
的变量中,然后使用该偏移量在动画结束时定义一个新的目标。move_cam()
函数最终如下所示:
const move_cam = () => {
camera_is_moving = true;
const offset = {
x: controls.target.x - camera.position.x,
y: controls.target.y - camera.position.y,
z: controls.target.z - camera.position.z,
};
const new_pos = { ...marker.position };
new_pos.y = CAMERA_HEIGHT;
gsap.to(camera.position, {
duration: 2,
x: new_pos.x,
y: new_pos.y,
z: new_pos.z,
onComplete: () => {
controls.target.x = offset.x + camera.position.x;
// controls.target.y= offset.x + camera.position.y;
controls.target.z = offset.x + camera.position.z;
offset.x = controls.target.x - camera.position.x;
offset.y = controls.target.y - camera.position.y;
offset.z = controls.target.z - camera.position.z;
camera_is_moving = false;
}
});
};
我确信它会起作用,我也确实做到了,但在动画结束时,相机有点抽搐,好像我分配的新目标并不完全正确:
如果你仔细看动图,就在动画的最后,摄像机会有一点卡顿,有时很明显,有时只是一个小动作。
我不知道是什么原因造成的,我的目标是相机的旋转保持与动画之前相同,所以我认为如果我偏移相机的目标与相机本身相同,它会工作,但显然,它没有。
有人能帮我吗?
我上传了这个项目在这个Github repo如果你想尝试和明白我的意思。完整的js文件是here。
先谢谢你。
1条答案
按热度按时间2fjabf4q1#
我设法解决了这个问题,方法是用gsap单独为相机目标设置动画,而不是在
onComplete()
回调中设置其值,因此move_cam()
函数的结果如下:我完全解决了我的问题,但我仍然不知道为什么以前的代码不工作。