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