threejs项目中,当模型很大的时候,我们观察模型的某个部位的细节时,就需要让相机靠近对应的区域以达到我们想要的效果,今天我们来实现这个效果。

threejs版本

使用到的threejs版本

"three": "^0.154.0",

threejs使用gsap实现相机飞行靠近观察设备

首先对模型进行处理,在模型上添加对应的设备,并添加名称,然后根据名称获取位置,再使用gsap来将将相机移到对应的区域。

我们使用Blender给模型添加5个点,5个点的位置自己按需在模型的对应位置添加即可。5个点的名称分别为 摄像机 水浸 温湿度 灯光 烟感。后面我们会通过名称来寻找坐标。

在页面底部写一个列表

我们在页面底部写一个列表,通过点击后进行后续操作。

<div class="container">
  <div class="list">
        class="list-item"
        v-for="item in list"
        :key="item"
        @click="handleClick(item.name)"
      {{ item.name }}
        class="list-item"
        @click="handleClick('默认视角')"

我们通过名称查询找到对应名称的点,获取坐标,这里我们需要两个坐标,一个是设备点的坐标,一个是相机的位置,我们需要给相机一个新的位置,但是这个位置不能和设备是同一个位置。

我们可以通过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 运行