先看效果:
<template><div><el-container><el-main><div class="box-card-left"><div id="threejs" style="border: 1px solid red"></div><div class="box-right"><pre style="font-size: 16px"></pre><el-button type="primary" @click="start">开始漫游</el-button><el-button type="primary" @click="end">结束漫游</el-button></div></div></el-main></el-container></div>
</template>
<script>
import Drawer from "@/components/Drawer.vue";
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";export default {components: { Drawer },data() {return {name: "",cameraX: 200,cameraY: 200,cameraZ: 200,scene: null,camera: null,renderer: null,mesh: null,mesh_sun: null,geometry: null,group: null,axis: null,texture: null,loader: null,animationId: null,line: null,lineFlag: true,circleFlag: true,catmullRowCurve3: null,controls: null,request: null,r: 300,angle: 0,i: 0,points:[]};},created() {},mounted() {this.name = this.$route.query.name;this.init();},methods: {end(){window.cancelAnimationFrame(this.request)},goBack() {this.$router.go(-1);},start() {this.points = this.catmullRowCurve3.getPoints(220);this.render();},render() {if(this.i < this.points.length-1) {this.camera.position.copy(this.points[this.i]);this.camera.lookAt(this.points[this.i+1]);this.camera.updateProjectionMatrix();this.controls.target.copy(this.points[this.i+1]);this.controls.update();this.i++;} else {this.i = 0;}this.renderer.render(this.scene, this.camera);this.request = requestAnimationFrame(this.render);},// 管道漫游案例:首先创建一个管道;管道使用纹理贴图;获取管道的扫描线上的 n个点;相机固定在 i 点, lookAt i+1 点位置;init() {// 1,创建场景对象this.scene = new this.$three.Scene();// 创建缓存几何体对象this.geomery = new this.$three.BufferGeometry();// 通过 Vector3(x,y,z) 创建顶点数据var pointsArr = [new this.$three.Vector3(0, 0, 0),new this.$three.Vector3(100, 0, 0),new this.$three.Vector3(100, 0, 100),new this.$three.Vector3(0, 100, 100),new this.$three.Vector3(-50, 50, 50),new this.$three.Vector3(0, 0, 0),];// 创建三维样条曲线对象(参数是三维点数组)this.catmullRowCurve3 = new this.$three.CatmullRomCurve3(pointsArr);// 获取三维样条曲线上的100个点const points = this.catmullRowCurve3.getPoints(220);// 设置缓存点模型的点数据this.geomery.setFromPoints(points);// 创建线材质对象this.material = new this.$three.LineBasicMaterial({ color: 0xaabb11 });// 创建线模型对象this.line = new this.$three.Line(this.geomery, this.material);this.scene.add(this.line);// 创建管道缓冲几何体const tubeGeometry = new this.$three.TubeGeometry(this.catmullRowCurve3, 104, 10, 36, false);// 创建网格材质对象const meshBasicMaterial = new this.$three.PointsMaterial({color: 0xbbddff,// side: this.$three.DoubleSide});const mesh = new this.$three.Points(tubeGeometry,meshBasicMaterial);this.scene.add(mesh);// 创建透视投影相机对象this.camera = new this.$three.PerspectiveCamera(90, 1, 0.01, 3000);this.camera.position.set(200, 200, 200);this.camera.lookAt(0, 0, 0);// 创建辅助坐标轴对象const axesHelper = new this.$three.AxesHelper(150);this.scene.add(axesHelper);// 创建渲染器对象this.renderer = new this.$three.WebGLRenderer();this.renderer.setSize(1000, 800);this.renderer.render(this.scene, this.camera);document.getElementById("threejs").appendChild(this.renderer.domElement);// 创建空间轨道控制器对象this.controls = new OrbitControls(this.camera, this.renderer.domElement);this.controls.addEventListener("change", () => {this.renderer.render(this.scene, this.camera);});},},
};
</script>
//
<style lang="less" scoped>
.msg {padding: 20px;text-align: left;display: flex;justify-content: flex-start;flex-wrap: wrap;.span {margin: 0 30px 30px 0;// white-space: nowrap;}.p {text-align: left;}
}
.box-card-left {display: flex;align-items: flex-start;flex-direction: row;width: 100%;.box-right {text-align: left;padding: 10px;.xyz {width: 100px;margin-left: 20px;}.box-btn {margin-left: 20px;}}
}
</style>