先看效果:
<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>