先看效果:
<template>
<div>
<el-container>
<el-header
style="
display: flex;
align-items: center;
justify-content: space-between;
"
>
<el-page-header @back="goBack" :content="name + '详情页面'">
</el-page-header>
</el-header>
<el-main>
<div class="box-card-left">
<div id="threejs" style=""></div>
<div class="box-right"></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 { onlyEnterMoney } from "@/utils/fn.js";
export default {
components: { Drawer },
data() {
return {
radio1: "",
radio2: "",
name: "",
x: 0,
y: 0,
z: 0,
cameraX: 200,
cameraY: 200,
cameraZ: 200,
scene: null,
camera: null,
renderer: null,
mesh: null,
mesh_moon: null,
mesh_sun: null,
geometry: null,
group1: null,
group2: null,
axis: null,
group1_arr: [],
group2_arr: [],
};
},
created() {},
mounted() {
this.name = this.$route.query.name;
this.init();
},
methods: {
goBack() {
this.$router.go(-1);
},
init() {
// 1,创建场景对象
this.scene = new this.$three.Scene();
// 2,创建组对象
this.group1 = new this.$three.Group();
this.group2 = new this.$three.Group();
// 3,调用封装方法创建mesh
this.mesh_sun = this.mesh_meth();
const mesh = this.mesh_meth(60,0x0ACDE9);
this.mesh_moon = this.mesh_meth(30,0xF5E904);
this.mesh_moon.position.set(150,0,0);
this.group1.add(mesh, this.mesh_moon);
this.group1.position.set(400,0,0);
this.group2.add(this.mesh_sun, this.group1);
this.scene.add(this.group2);
// 4,创建辅助坐标轴对象
const axesHelper = new this.$three.AxesHelper(220);
this.scene.add(axesHelper);
// 5,创建 正交相机 对象;
// 在这种投影模式下,无论物体距离相机距离远还是近,在最终渲染的图片中物体的大小都保持不变
this.camera = new this.$three.OrthographicCamera(-1000,1000,1000,-1000,1,2000);
// this.camera = new this.$three.PerspectiveCamera(50,1,-1300,1300);
this.camera.position.set(300,300,300);// 设置相机位置
// this.camera.position.set(700,700,800);// 设置相机位置
this.camera.lookAt(0,0,0); // 设置相机朝向的位置
this.scene.add(this.camera);
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);
// 9, 创建相机空间轨道控制器
const controls = new OrbitControls(this.camera, this.renderer.domElement);
controls.addEventListener('change', () => {
this.renderer.render(this.scene,this.camera);
});
// 声明一个三维向量来表示某个坐标
const worldPosition = new this.$three.Vector3();
this.mesh_moon.getWorldPosition(worldPosition);
console.log('世界坐标',worldPosition);
console.log('本地坐标',this.mesh_moon.position);
// 创建可视化mesh1的局部坐标系
const mesh1_axesHelper = new this.$three.AxesHelper(150);
// this.mesh_moon.add(mesh1_axesHelper);
this.renderFun1();
},
mesh_meth(r=100,color= 0xF90E49) {
// 2,创建球缓冲结合体对象
const box_geometry = new this.$three.SphereGeometry(r);
// 3,创建Toon网格材质对象;一种实现卡通着色的材质。
// const material = new this.$three.MeshToonMaterial({color:color});
const material = new this.$three.MeshBasicMaterial({color:color});
return new this.$three.Mesh(box_geometry, material);
},
renderFun1() {
this.group2.rotateY(0.01);
this.mesh_moon.rotateY(0.05);
this.group1.rotateY(0.03);
this.renderer.render(this.scene, this.camera);
window.requestAnimationFrame(this.renderFun1)
},
getRandomColor() {
let c1 = this.random(0, 255);
let c2 = this.random(0, 255);
let c3 = this.random(0, 255);
return new this.$three.Color("rgb(" + c1 + ", " + c2 + ", " + c3 + ")");
},
/**
* 产生随机整数,包含下限值,但不包括上限值
* @param {Number} lower 下限
* @param {Number} upper 上限
* @return {Number} 返回在下限到上限之间的一个随机整数
*/
random(lower, upper) {
return Math.floor(Math.random() * (upper - lower)) + lower;
},
},
};
</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 {
padding-left: 20px;
}
}
</style>