<template> <div class="overview"> <div class="top"> <div class="block" v-for="(value,key,index) in data" :key="index" @click="btnClick(value)"> <image-block :data="value"/> </div> </div> <div ref="body" class="body"> <left ref="left" class="left"/> <div ref="right" class="right"> <div class="title">{{active}}</div> <div class="angle">横滚角: {{roll}} <br/>俯仰角: {{pitch}} <br/>航向角: {{heading}} </div> <div ref="demo1"/> </div> </div> </div> </template> <script> import { getRobotList,getRobotDetail } from '@/api/robot' import ImageBlock from "./components/imageBlock"; import Left from './left' import * as THREE from 'three' import OrbitControls from 'three-orbitcontrols' import dat from 'dat.gui' export default { name: 'Device', components: { Left,ImageBlock, THREE, dat,OrbitControls}, data() { return { active: '飞翼滑翔机一号', roll: '45.21°', pitch: '51.41°', heading: '93.00°', controls: null, scene: null, camera: null, renderer: null, plane:null, data:[ // {name:'飞翼滑翔机一号',gltf:''}, // {name:'飞翼滑翔机二号',gltf:''}, // {name:'飞翼滑翔机三号',gltf:''}, // {name:'飞翼滑翔机四号',gltf:''}, // {name:'飞翼滑翔机五号',gltf:''}, // {name:'飞翼滑翔机六号',gltf:''}, // {name:'飞翼滑翔机七号',gltf:''}, // {name:'飞翼滑翔机八号',gltf:''} ] } }, created() { this.$nextTick(() => { this.init() }) }, methods: { btnClick(val){ this.active = val.name getRobotDetail(val.id).then(res => { if (res.code === 200) { this.$refs.left.init(res.data) this.roll = res.data.rollAngle + '°' this.pitch = res.data.pitchAngle + '°' this.heading = res.data.headingAngle + '°' } }) }, init () { this.initList() this.initMesh() }, initList(){ getRobotList().then(res => { if (res.code === 200) { this.data = res.data.map(item => { return {name:'飞翼滑翔机'+item.robotId+'号',id:item.robotId,gltf:''} }) this.btnClick(this.data[0]) } }) }, initMesh () { this.scene = new THREE.Scene() // 场景 this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000) // 相机.视场,长宽比,近面,远面 this.camera.position.x = -20 this.camera.position.y = 40 this.camera.position.z = 30 this.camera.lookAt(this.scene.position) this.renderer = new THREE.WebGLRenderer({ antialias: true })// 渲染器 this.renderer.setSize(this.$refs.right.clientWidth,this.$refs.right.clientHeight) this.renderer.shadowMapEnabled = true // 开启阴影 let axes = new THREE.AxisHelper(20) // 坐标轴 let planeGeometry = new THREE.PlaneGeometry(60, 20, 10, 10) // 生成平面 let planeMaterial = new THREE.MeshLambertMaterial({color: 0x00ffff}) // 材质 this.plane = new THREE.Mesh(planeGeometry, planeMaterial) this.plane.rotation.x = -0.5 * Math.PI this.plane.position.x = 0 this.plane.position.y = 0 this.plane.position.z = 0 this.plane.receiveShadow = true let spotLight = new THREE.SpotLight(0xffffff) spotLight.position.set(-40, 60, -10) spotLight.castShadow = true this.scene.add(axes) // 场景添加坐标轴 this.scene.add(this.plane) // 向该场景中添加物体 this.scene.add(spotLight) this.$refs.demo1.append(this.renderer.domElement) this.renderer.render(this.scene, this.camera) this.controls = new OrbitControls(this.camera, this.renderer.domElement); //摄像机和容器div 注意事div // 使动画循环使用时阻尼或自转 意思是否有惯性 this.controls.enableDamping = true; //是否可以缩放 this.controls.enableZoom = true; //是否自动旋转 this.controls.autoRotate = true; // //设置相机距离原点的最远距离 // this.controls.minDistance = 200; //设置相机距离原点的最远距离 this.controls.maxDistance = 600; //是否开启右键拖拽 this.controls.enablePan = true; this.renderScene() }, renderScene () { let {controls, plane, scene, camera, renderer} = this // plane.rotation.x += controls.rotationSpeed // plane.rotation.y += controls.rotationSpeed // plane.rotation.z += controls.rotationSpeed requestAnimationFrame(this.renderScene) renderer.render(scene, camera) } } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .overview{ display: flex; flex-direction: column; padding-right: 30px; width: 100%; height: 100%; .title{ color: #ffffff; font-size: 20px; font-weight: bold; position: absolute; top: 30px; left: 360px; } .angle{ color: #00DAE2; font-size: 17px; position: absolute; top: 80px; left: 360px; line-height: 25px; } .top{ margin: 10px 30px; display: flex; flex-direction: row; .block{ width: 12.5%; height: 30px; margin-right: 10px; } } .body{ position:relative; width: 100%; flex: 1; display: flex; flex-direction: row; .left{ margin-left: 20px; min-width: 300px; width: 300px; display: flex; flex-direction: column; padding-bottom: 20px; } .right{ flex: 1; /*background-color: #E6A23C;*/ margin-left: 20px; margin-top: 5px; margin-bottom: 25px; } } .map{ width: 100%; flex: 1; background-color: white; } } </style>