threejs项目中,当模型很大的时候,我们观察模型的某个部位的细节时,就需要让相机靠近对应的区域以达到我们想要的效果,今天我们来实现这个效果。
threejs版本
使用到的threejs版本
"three": "^0.154.0",
演示地址
实例效果
动态效果
实现思路
首先对模型进行处理,在模型上添加对应的设备,并添加名称,然后根据名称获取位置,再使用gsap来将将相机移到对应的区域。
模型处理
我们使用Blender给模型添加5个点,5个点的位置自己按需在模型的对应位置添加即可。5个点的名称分别为 摄像机 水浸 温湿度 灯光 烟感。后面我们会通过名称来寻找坐标。
在页面底部写一个列表
我们在页面底部写一个列表,通过点击后进行后续操作。
<div class="container">
<div class="list">
<div
class="list-item"
v-for="item in list"
:key="item"
@click="handleClick(item.name)"
>
{{ item.name }}
</div>
<div
class="list-item"
@click="handleClick('默认视角')"
>
默认视角
</div>
</div>
</div>
相机飞入
我们通过名称查询找到对应名称的点,获取坐标,这里我们需要两个坐标,一个是设备点的坐标,一个是相机的位置,我们需要给相机一个新的位置,但是这个位置不能和设备是同一个位置。
我们可以通过addScalar方法来定义相机的位置。
然后使用gsap将相机移动到这个点的附近,并设置相机的视角,这样相机飞入的效果就实现了。
flyToEquipment(equipmentName) {
const object = scene.getObjectByName(equipmentName);
if (!object) return; // 如果场景中没有该对象,直接返回
const targetPosition = new THREE.Vector3();
object.getWorldPosition(targetPosition); // 获取设备的世界坐标
const targetPosition2 = targetPosition.clone().addScalar(1); // 向量 x y z 坐标分别在基础上增加1 让相机的位置和目标位置有一定的距离
// 获取初始相机位置和目标位置
const initialCameraPosition = {x: camera.position.x, y: camera.position.y, z: camera.position.z};
// 相机位置和目标位置的副本
const targetCameraPosition = {x: targetPosition2.x, y: targetPosition2.y, z: targetPosition2.z};
const initialLookAt = {x: 0, y: 0, z: 0};
const targetLookAt = {x: targetPosition.x, y: targetPosition.y, z: targetPosition.z};
// 创建一个GSAP动画
gsap.to(initialCameraPosition, {
x: targetCameraPosition.x,
y: targetCameraPosition.y,
z: targetCameraPosition.z,
duration: 1, // 动画持续1秒
onUpdate: () => {
camera.position.set(initialCameraPosition.x, initialCameraPosition.y, initialCameraPosition.z);
},
onComplete: () => {
controls.target.set(targetLookAt.x, targetLookAt.y, targetLookAt.z); // 设置OrbitControls的目标位置
controls.update(); // 更新OrbitControls的内部状态
}
});
gsap.to(initialLookAt, {
x: targetLookAt.x,
y: targetLookAt.y,
z: targetLookAt.z,
duration: 1, // 动画持续1秒
onUpdate: () => {
camera.lookAt(new THREE.Vector3(initialLookAt.x, initialLookAt.y, initialLookAt.z));
},
onComplete: () => {
controls.target.set(targetLookAt.x, targetLookAt.y, targetLookAt.z); // 设置OrbitControls的目标位置
controls.update(); // 更新OrbitControls的内部状态
}
});
},
相机恢复
相机飞入后,我们还需要让相机恢复到默认的位置,通过事先设置的默认相机坐标以及相机视角,我们通过gsap让其恢复即可。
resetToDefaultView() {
// 获取当前相机位置和lookAt(OrbitControls的目标)位置
const initialCameraPosition = { x: camera.position.x, y: camera.position.y, z: camera.position.z };
const initialLookAt = { x: controls.target.x, y: controls.target.y, z: controls.target.z };
// 使用GSAP动画平滑过渡相机位置到默认位置
gsap.to(initialCameraPosition, {
x: defaultCameraPosition.x,
y: defaultCameraPosition.y,
z: defaultCameraPosition.z,
duration: 1,
onUpdate: () => {
camera.position.set(initialCameraPosition.x, initialCameraPosition.y, initialCameraPosition.z);
},
onComplete: () => {
controls.update();
}
});
// 使用GSAP动画平滑过渡lookAt到默认lookAt
gsap.to(initialLookAt, {
x: defaultLookAt.x,
y: defaultLookAt.y,
z: defaultLookAt.z,
duration: 1,
onUpdate: () => {
camera.lookAt(new THREE.Vector3(initialLookAt.x, initialLookAt.y, initialLookAt.z));
},
onComplete: () => {
controls.target.set(initialLookAt.x, initialLookAt.y, initialLookAt.z);
controls.update();
}
});
},
到这里我们的相机飞行靠近设备以及离开设备的动画效果就完成了。
学习笔记
当前内容为 threejs视频教程 《WebGL/Three.js前端高薪3D可视化》 -17.动画库tween.js-点按钮,相机飞行靠近观察设备-学习笔记
笔记代码
笔记代码项目基于vue3 vite js nodejs16 运行