vue3+three.js实现汽车沿着轨迹运动

<script setup lang="ts">
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { onMounted } from "vue";
let curve: any = null,
 model: any = null;
let progress = 0; // 物体运动时在运动路径的初始位置,范围0~1
const velocity = 0.001; // 影响运动速率的一个值,范围0~1,需要和渲染频率结合计算才能得到真正的速率
let curve: any = null,
  model: any = null;
let progress = 0; // 物体运动时在运动路径的初始位置,范围0~1
const velocity = 0.001; // 影响运动速率的一个值,范围0~1,需要和渲染频率结合计算才能得到真正的速率
onMounted(() => {
  init();
  animate();
  // 创建一个封闭的运动轨迹
  createTrace();
  // 物体沿线移动方法
  objectMovement();
  // 汽车模型
  loadingModel();
});

一 ,创建一个封闭的运动轨迹

// 创建一个封闭的运动轨迹
function createTrace() {
  // 创建一个封闭的运动轨迹
  curve = new THREE.CatmullRomCurve3(
    [
      new THREE.Vector3(-210, 2, 53), // x -150, y 2, z 50 
      new THREE.Vector3(150, 2, 53),
      new THREE.Vector3(150, 2, 66),
      new THREE.Vector3(-210, 2, 66),
    ],
    false
  );
  curve.curveType = "catmullrom";
  curve.closed = true; //设置是否闭环
  curve.tension = 0.1; //设置线的张力,0为无弧度折线
  // 为曲线添加材质在场景中显示出来,不显示也不会影响运动轨迹,相当于一个Helper
  const points = curve.getPoints(50);
  const geometry = new THREE.BufferGeometry().setFromPoints(points);
  const material = new THREE.LineBasicMaterial({ color: 0x000000 });
  material.transparent = true; // 启用透明
  material.opacity = 0; //  设置为完全透明 
  // 创建要添加到场景中的最后一个对象
  const curveObject = new THREE.Line(geometry, material);
  scene.add(curveObject);
}

二,模型沿线移动的方法

// 物体沿线移动方法
function objectMovement() {
  if (curve == null || model == null) {
    console.log("Loading");
  } else {
    if (progress <= 1 - velocity) {
      const point = curve.getPointAt(progress); //获取样条曲线指定点坐标
      const pointBox = curve.getPointAt(progress + velocity); //获取样条曲线指定点坐标
      if (point && pointBox) {
        model.position.set(point.x, point.y, point.z);
        model.lookAt(pointBox.x, pointBox.y, pointBox.z);//因为这个模型加载进来默认面部是正对Z轴负方向的,所以直接lookAt会导致出现倒着跑的现象,这里用重新设置朝向的方法来解决。
        var targetPos = pointBox; //目标位置点
        var offsetAngle = 1; //目标移动时的朝向偏移
        // 以下代码在多段路径时可重复执行
        var mtx = new THREE.Matrix4(); //创建一个4维矩阵
        // .lookAt ( eye : Vector3, target : Vector3, up : Vector3 ) : this,构造一个旋转矩阵,从eye 指向 target,由向量 up 定向。
        
       //  console.log('@model.position',model.position)
        mtx.lookAt(model.position,targetPos, model.up ); //设置朝向
        mtx.multiply(
          new THREE.Matrix4().makeRotationFromEuler(
            new THREE.Euler(0, offsetAngle, 0)
          )
        );
        var toRot = new THREE.Quaternion().setFromRotationMatrix(mtx); //计算出需要进行旋转的四元数值
        model.quaternion.slerp(toRot, 0.75);
      }
      progress += velocity;
    } else {
      progress = 0;
    }
  }
}

三,加载模型

// 小米汽车
const loadingModel= () => {
  const loader = new GLTFLoader();
  loader.setPath("/public/data/gltf/"); //  模型路劲
  loader.load("JZ10.gltf", function (gltf: any) {
    gltf.scene.position.set(-140, 2, 50); // 模型位置
    gltf.scene.traverse(function (child: any) {
      if (child.isMesh) {
        child.castShadow = true; //阴影
        child.receiveShadow = true; //接受别人投的阴影
      }
    });
    // 设置模型的大小
    const modelScale = 3.5; // 定义模型的缩放比例
    gltf.scene.scale.set(modelScale, modelScale, modelScale);
   //  gltf.scene.rotation.y = Math.PI; // 模型旋转180
    // gltf.scene.rotateY(Math.PI / 2);
    scene.add(gltf.scene);
    model = gltf.scene;
  });
};

const animate = () => {
  requestAnimationFrame(animate);
  moveOnCurve();
  renderer.render(scene, camera);
  // render();
};

最后看结果

5

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你好!对于使用Vue 3、TypeScript和Vite来实现一个看房自由的应用,可以结合Three.js这个D图形库来实现。下面是一个简单的步骤指南: 1. 首先,确保你已经安装了Node.js和npm。 2. 创建一个新的Vue项目,可以使用Vue CLI来快速搭建一个基本的项目结构。 ```bash npm install -g @vue/cli vue create my-project ``` 3. 在Vue项目中安装Vite作为开发服务器。 ```bash cd my-project npm install -D create-vite npx create-vite ``` 4. 安装Three.js库和相关依赖。 ```bash npm install three ``` 5. 在Vue组件中引入Three.js库,并开始编写代码来实现看房自由功能。 ```typescript <template> <div ref="container"></div> </template> <script lang="ts"> import { ref, onMounted } from 'vue'; import * as THREE from 'three'; export default { setup() { const container = ref(null); onMounted(() => { // 创建场景、相机和渲染器 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); // 设置渲染器的大小并将其添加到DOM中 renderer.setSize(window.innerWidth, window.innerHeight); container.value.appendChild(renderer.domElement); // 创建一个立方体并将其添加到场景中 const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 设置相机的位置 camera.position.z = 5; // 动画循环 const animate = function () { requestAnimationFrame(animate); // 使立方体旋转起来 cube.rotation.x += 0.01; cube.rotation.y += 0.01; // 渲染场景和相机 renderer.render(scene, camera); }; animate(); }); return { container, }; }, }; </script> <style> #container { width: 100%; height: 100%; } </style> ``` 这只是一个简单的示例,你可以根据自己的需求来构建更复杂的场景和交互逻辑。希望对你有所帮助!如有任何疑问,欢迎继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸥总

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值