VUE2+THREE.JS项目搭建

9 篇文章 0 订阅

简介

three.js 是一个 是基于WebGL 封装的一个易于使用且轻量级的 3D 库,ThreeJS 对 WebGL 提供的接口进行了非常好的封装,简化了很多细节,大大降低了学习成本,同时也极大地提高了性能。用户不需要详细地学习 WebGL,就能轻松创作出三维图形,是前端开发者研发 3D WEB 应用的主要工具

学习文档推荐

  • WebGl中文档:可以了解到three.js最基础的知识点,可以对相机,场景,控制器有初步的认识与了解
  • 3D查看器:查看3D模型的在线网站

搭建

1.下载three.js

npm install --save three

npm install three-obj-mtl-loader :mtl模型加载

npm install three-orbit-controls :控制器

npm install three-stats:性能检测器

2.新建3DWorkShop.vue文件

用于3D车间最外层文件

3.创建utils/three/tool.js

将所有模型文件类型的获取方法写在一个js文件中

import { MTLLoader } from 'three-obj-mtl-loader'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import {  FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'


// 加载obj,mtl文件
export function objloader(path) {
  return new Promise(resolve => {
    var mtlLoader = new MTLLoader()
    //  初始化obj
    var objLoader = new OBJLoader()
    // 加载mtl文件
    mtlLoader.load(`three/${path}.mtl`, (mtl) => {
      // 初始化
      mtl.preload()
      // 加载贴图
      objLoader.setMaterials(mtl)
      objLoader.load(`three/${path}.obj`, (obj) => {
        resolve({
          mtl,
          obj
        })
      })
    })
  })
}

// 加载fbx文件
export function fbxloader(path) {
  return new Promise(resolve => {
    var loader = new FBXLoader()
    loader.load(`three/${path}.fbx`, (fbx) => {
      resolve(fbx)
    }, function (xhr) {
      // 控制台查看加载进度xhr
      // 通过加载进度xhr可以控制前端进度条进度   Math.floor:小数加载进度取整
      console.log('加载进度' + Math.floor(xhr.loaded / xhr.total * 100) + '%');
    })
  })
}
// 加载gtlf文件
export function gltfloader(path) {
  return new Promise(resolve => {
    var loader = new GLTFLoader()
    loader.load(`three/${path}.gltf`, (gltf) => {
      resolve(gltf)
    })
  })
}

4.创建components/three/draw.vue[重点]

创建html

<div class="draw" ref="draw">
	<div id="webgl" v-if="isShowWebgl"></div>
</div>

注意点:要将three相关的参数定义到vue之外,不可以放到vue的data里(会导致卡顿问题)
具体原因是:three的相关参数会经常变动,而vue又会对data里面的变量进行变化追踪,所以就会卡
例如:
在这里插入图片描述

4.1 引入文件

import * as THREE from "three"; //  三维
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; //  控制器

4.2 初始化场景

initScene(){
   scene = new THREE.Scene(); //  场景对象Scene
}

4.3 初始化渲染器

initRenderer(){
   	renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
	//   设置渲染区域尺寸
	renderer.setSize(this.$refs.draw.offsetWidth, this.$refs.draw.offsetHeight);
	//   开启渲染阴影
	renderer.shadowMap.enabled = true;
	renderer.shadowMap.type = THREE.PCFSoftShadowMap;
	renderer.hadowMapEnabled = true;
	//  body元素中插入canvas对象
	this.$refs.draw.appendChild(renderer.domElement);
}

4.4 初始化光源

//   初始化光源
initLight() {
	//增加环境光(环境光颜色,环境光强度)
	const ambientLight = new THREE.AmbientLight(0xffffff, 2);
	ambientLight.name = "ambientLight";
	scene.add(ambientLight);

	//增加太阳光
	const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
	directionalLight.name = "directionalLight";
	directionalLight.position.set(8000, 8000, -2000);
},

4.5 初始化相机(人眼模式)

sightline = { 
    scale: 45, //  视线比例
	type: "PerspectiveCamera", //  相机的类型
	posiy: [-5000, 7000, 16000], //  相机位置
};
//   初始化相机
initCamera() {
	const k = this.$refs.draw.offsetWidth / this.$refs.draw.offsetHeight; //  窗口宽高比
	camera = new THREE.PerspectiveCamera(this.sightline.scale, k, 1, 100000);
	camera.position.set(this.sightline.posiy[0], this.sightline.posiy[1], this.sightline.posiy[2]);
	camera.up.set(0, 1000, 0);
	camera.lookAt(0, 0, 1);
},

4.6 初始化控制器

//   初始化控制
initOrbitControls() {
	controls = new OrbitControls(camera, renderer.domElement); //  创建控件对象
	controls.target.set(0, 0.5, 0); //控制器轴的方向,Y轴向上
	controls.update(); //控制器更新
},

4.7 初始化动画

//   设置动画
animate() {
	if (!renderer) {
		return;
	}
	if (this.count < 2) {
		this.count++;
		renderer.render(scene, camera);
		controls.update();
	}
	if (animateId) cancelAnimationFrame(animateId);
	animateId = requestAnimationFrame(this.animate);
},

4.8 添加全局方法

//   添加全局方法
addmeth() {
	//   监听窗口尺寸变化
	window.addEventListener("resize", this.changeSize, false);
},
//   监听尺寸变化
changeSize() {
	//   重置渲染器输出画布canvas尺寸
	renderer.setSize(this.$refs.draw.offsetWidth, this.$refs.draw.offsetHeight);
	const k = this.$refs.draw.offsetWidth / this.$refs.draw.offsetHeight; //  窗口宽高比
	//  重置相机投影的相关参数
	camera.aspect = k;
	//   需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
	camera.updateProjectionMatrix();
},

4.9 加载模型

<draw ref="draw" :initLoader="initLoader" :eqpList="eqpList" />

在3DWorkShop的methods里:

import { fbxloader } from "@/utils/three/tool";

// 引入模型文件
initLoader() {
//sip 是文件名[文件必须存放到public里,我放的位置是public/three/sip.fbx]
	fbxloader(sip).then(obj=>{
		this.$refs.draw.addScene(fbx);
	})
},

4.10 执行方法

mounted(){
	this.init();//初始化渲染	
	this.animate();//添加动画
	this.addmeth();//添加事件
},
init(){
	//初始化场景
	this.initScene();
	//   初始化渲染对象
	this.initRenderer();
	//   初始化模型
	this.initLoader();
	//   初始化光源
	this.initLight();
	//   初始化相机
	this.initCamera();
	//   初始化控制
	this.initOrbitControls();
}

你好!对于使用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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值