负责检测是否出现问题 根据检查顺序变色改变当前检测状态 主要代码
// 组件 传递
<Three :num="num" :objNum="objNum" @finish="finish"></Three>
// 方法传递
finish(){
this.check(0);
},
check(num) {
if (this.dataList.length <= num) {
this.dataList.map((item) => (item.flag = false));
this.checkIndex = -1;
this.loading = false;
this.dataList.every((val) => {
if (val.status == 0) {
this.setLoading();
}
});
this.timer = setTimeout(() => {
this.loadings.close();
this.getResult();
}, 3000);
return
}
this.checkIndex = num;
this.$bus.$emit('Trigger',this.dataList[num])
let time = 1000 + Math.random() * 1000;
this.timer = setTimeout(() => {
this.num = num;
this.objNum = this.dataList[num];
this.dataList.forEach((item, index) => {
this.dataList[num].status = 0;
this.dataList[num].result = 0
// if(this.dataList[1]){ // 测试如果出现错
// this.dataList[1].status = 1;
// this.dataList[1].result = 1
// }
index == num ? (item.flag = true) : (item.flag = false);
});
// 诊断完成
// this.$bus.$emit('tests',this.objNum)
this.check(num + 1);
}, time);
},
// 组件当中利用 生命周期 mounted 接收跨层级bus值
this.$bus.$on('Trigger', os => {
if(os.designation == undefined) return
this.autoTransform(os);
})
// 方法
autoTransform(newName) {
// 做一些判断条件比如名称或者id 赋值改变状态
}
完整代码
<template>
<div class="start">
<div class="record">
<tags-top :image="image" :isShow="isShow">故障诊断中...</tags-top>
<div class="start-isErr">
<el-card shadow="always" class="start-isErr">
<div class="start-tanc">
<div class="start-center">
<div>
<ul class="start-box">
<li v-for="(item, index) in dataList" class="auto-move">
<div class="flex-juz tancs" :class="checkIndex==index ? 'active': ''">
<div class="tancs_zhu">
<div class="left">{{ item.name }}:</div>
<div class="right">
{{
item.status == 1 ? "诊断数据分析中…" : "诊断完成"
}}
</div>
</div>
<div style="margin-right: 50px" class="status_image">
<img v-if="item.result == 1" :src="statusIMG.image" alt />
<img v-else :src="statusIMG.success" alt />
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</el-card>
</div>
<el-card
shadow="always"
style="border-radius: 10px; margin-top: 10px"
:body-style="{height:cardHeight+'px'}"
v-if="cardHeight>0"
>
<div class="panzer">
<Three :num="num" :objNum="objNum" @finish="finish"></Three>
</div>
</el-card>
<!-- <div class="start-boutton">
<el-button type="primary" @click="$router.go(-1)">返回</el-button>
<el-button type="primary" @click="getResult()" v-if="!loading"
>下一步</el-button
>
</div>-->
</div>
</div>
</template>
<script>
import err from "@/assets/images/u143.png";
import u191 from "../../assets/images/u191.png";
import image from "../../assets/images/u121.png";
import success from "@/assets/images/u139.png";
import tagsTop from "@/components/TagsTop";
import Three from "@/components/three/three-check";
export default {
name: "",
components: { tagsTop, Three },
props: {},
data() {
return {
icon: "el-icon-search",
isShow: false,
cardHeight: 0,
image: image,
u191: u191,
loading: true,
checkIndex: -1,
num: 0,
objNum: {},
timer: null,
statusIMG: {
image: err,
success: success,
},
dataList: [
{
name: "目标镜",
designation: "paoshuan01",
result: 1,
status: 0,
flag: false,
},
{
name: "后轮",
designation: "lunzi01",
result: 1,
status: 0,
flag: true,
},
{
name: "支架",
designation: "maozhunjia01",
result: 1,
status: 0,
flag: false,
},
{
name: "头",
designation: "paoguan01",
result: 1,
status: 0,
flag: false,
},
{
name: "网支架",
designation: "paojia01",
result: 1,
status: 0,
flag: false,
},
],
// dataList: [
// {
// name: "控箱",
// result: 1,
// status: 1,
// flag: true,
// },
// {
// name: "陀螺",
// result: 1,
// status: 1,
// flag: false,
// },
// {
// name: "计算机",
// result: 1,
// status: 1,
// flag: false,
// },
// {
// name: "填机程控盒",
// result: 1,
// status: 1,
// flag: false,
// },
// {
// name: "放大机控制盒",
// result: 1,
// status: 1,
// flag: false,
// },
// {
// name: "控制盒",
// result: 1,
// status: 1,
// flag: false,
// },
// ],
index: 0,
};
},
computed: {},
watch: {},
created() {},
mounted() {
this.init();
},
methods: {
getResult() {
this.$router.push({
path: "/train/result",
});
},
init() {
this.getSize();
},
getSize() {
let h = window.innerHeight;
this.cardHeight = h - 320;
},
setLoading() {
this.timer = setTimeout(() => {
this.loadings = this.$loading({
lock: true,
text: "跳转中...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
}, 2000);
},
finish(){
this.check(0);
},
check(num) {
if (this.dataList.length <= num) {
this.dataList.map((item) => (item.flag = false));
this.checkIndex = -1;
this.loading = false;
this.dataList.every((val) => {
if (val.status == 0) {
this.setLoading();
}
});
this.timer = setTimeout(() => {
this.loadings.close();
this.getResult();
}, 3000);
return
}
this.checkIndex = num;
this.$bus.$emit('Trigger',this.dataList[num])
let time = 1000 + Math.random() * 1000000;
this.timer = setTimeout(() => {
this.num = num;
this.objNum = this.dataList[num];
this.dataList.forEach((item, index) => {
this.dataList[num].status = 0;
this.dataList[num].result = 0
// if(this.dataList[1]){ // 测试如果出现错
// this.dataList[1].status = 1;
// this.dataList[1].result = 1
// }
index == num ? (item.flag = true) : (item.flag = false);
});
// 诊断完成
// this.$bus.$emit('tests',this.objNum)
this.check(num + 1);
}, time);
},
// right(num) {
// if (this.dataList.right.length <= num) {
// this.dataList.right.map((item) => (item.flag = false));
// this.loading = false;
// return;
// }
// let time = 500 + Math.random() * 2000;
// setTimeout(() => {
// this.dataList.right.find((item, index) => {
// index == num ? (item.flag = true) : (item.flag = false);
// });
// this.dataList.right[num].status = 0;
// this.right(num + 1);
// }, time);
// },
},
beforeDestroy() {
if (this.timer) {
clearInterval(this.timer);
}
},
};
</script>
<style scoped lang="scss">
.start-isErr {
width: 100%;
border-radius: 10px;
.start-tanc {
width: 100%;
// display: flex;
.start-center {
overflow: hidden;
display: flex;
.start-box {
flex-wrap: wrap;
display: flex;
justify-content: space-between;
.auto-move {
width: 49.5%;
}
}
word-break: break-all;
word-wrap: break-word;
overflow: hidden;
.tancs {
.tancs_zhu {
// line-height: 50px;
display: flex;
width: 500px;
font-size: 19px;
font-weight: 500;
.left {
width: 50%;
text-align: center;
}
.right {
width: 50%;
text-align: left;
}
}
}
}
}
.active {
color: #fff;
background: #0066cb;
}
.status_image {
img {
width: 35px;
height: 35px;
}
}
}
.panzer {
position: relative;
height: 100%;
img {
width: 100%;
height: 100%;
vertical-align: middle;
object-fit: contain;
}
}
.start-boutton {
display: flex;
justify-content: center;
padding-top: 30px;
/deep/ .el-button {
width: 200px;
}
}
</style>
<template>
<div id="three_check_container" style="margin: auto" :style="{ width: width + 'px', height: height + 'px' }"></div>
</template>
<script>
import * as THREE from "three";
import { OBJLoader, MTLLoader } from "three-obj-mtl-loader";
import { DDSLoader } from "three/examples/jsm/loaders/DDSLoader";
const OrbitControls = require("three-orbit-controls")(THREE);
const helper = new THREE.BoxHelper();
export default {
// props: ['objNum'], // 从父组件接收
props: {
num: {
type: Number,
},
objNum: {
type: Object,
},
},
data() {
return {
composer: null,
outlinePass: null,
renderPass: null,
width: 1000,
height: 600,
scene: null,
camera: null,
renderer: null,
manager: null,
container: null,
watch_num: -1,
objs: [],
obj: {},
meshs: {},
new_Obj: {},
tests: false,
clone_obj: {},
isAuto: "",
models: [
{
id: "paoshuan01",
title: "目标镜",
tempera: 5,
execute: false,
color: true,
},
{
id: "lunzi01",
title: "火炮后轮",
tempera: 10,
execute: false,
color: true,
},
{
id: "maozhunjia01",
title: "火炮支架",
tempera: 60,
execute: false,
color: true,
},
{
id: "paoguan01",
title: "炮控头",
tempera: 80,
execute: false,
color: true,
},
{
id: "paojia01",
title: "伪装网支架",
tempera: 20,
execute: false,
color: true,
},
],
};
},
mounted() {
this.destroy();
this.init();
this.loadObj();
this.$bus.$on('Trigger', os => {
if(os.designation == undefined) return
this.autoTransform(os);
})
// this.grounds();
// this.handleClick()
},
destroyed() {
this.destroy();
},
watch: {
objNum:{
handler(newVal,oldData){
// this.autoTransform(newVal);
// console.log(newVal,"新");
},
// immediate: true,
deep:true
}
},
computed: {
reversedText() {
//这里的this指向的是当前的vue实例
return this.objNum
}
},
methods: {
// 初始化场景
init() {
this.container = document.getElementById("three_check_container");
this.width = this.container.parentNode.clientWidth;
this.height = this.container.parentNode.clientHeight;
/* 场景 */
this.scene = new THREE.Scene();
// this.scene.add(helper);
/* 相机 */
this.camera = new THREE.PerspectiveCamera(
20,
this.width / this.height,
0.7,
10000
);
this.camera.position.x = 700 * Math.sin(-30);
this.camera.position.y = 200 * Math.cos(-30);
this.camera.position.z = 400;
this.camera.lookAt({ x: 50, y: 0, z: 0 });
// this.camera.position.y = 80;
/* 渲染器 */
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.setSize(this.width, this.height);
this.renderer.setClearColor(0x1c1c1c, 1);
// this.renderer.autoClear = false;
this.container.appendChild(this.renderer.domElement);
this.control = new OrbitControls(
this.camera,
this.renderer.domElement
);
new OrbitControls(this.camera, this.renderer.domElement);
this.control.rotateSpeed = 0.3;
let angle = this.control.getPolarAngle(); // 获取当前垂直旋转度数
this.control.minPolarAngle = angle; // 设置垂直旋转度数
this.control.maxPolarAngle = angle; // 设置垂直旋转度数
this.control.enablePan = false; // 右键移动视角 是否启用
// this.control.enableRotate = false; // 左右视角旋转 是否启用
},
// 销毁场景
destroy() {
if (this.handle) {
cancelAnimationFrame(this.handle);
this.scene = null;
this.camera = null;
this.renderer = null;
this.manager = null;
this.container = null;
}
},
// 添加场地
grounds() {
const gridHelper = new THREE.GridHelper(
1000,
10,
0x888888,
0x444444
);
this.scene.add(gridHelper);
gridHelper.position.y = 100;
// this.gridHelper.rotateX(Math.PI/4);
//
const ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
this.scene.add(ambientLight);
const pointLight = new THREE.PointLight(0xfffafa, 0.5);
this.camera.add(pointLight);
pointLight.position.y = 100;
},
// 点击事件
handleClick(e) {
let raycaster = new THREE.Raycaster();
let mouse = new THREE.Vector3();
// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围
mouse.x = (e.layerX / this.width) * 2 - 1;
mouse.y = -(e.layerY / this.height) * 2 + 1;
// 通过摄像机和鼠标位置更新射线
raycaster.setFromCamera(mouse, this.camera);
let distance, num;
let obj;
this.objs.forEach((group, index) => {
// 计算物体和射线的焦点
let intersects = raycaster.intersectObjects(group.children);
// console.log(this.scene.children)
if (intersects.length > 0) {
if (!num || (num && distance > intersects[0].distance)) {
distance = intersects[0].distance;
num = index;
}
obj = this.objs[num];
// console.log(obj,"详情");
// meshs = obj.clone(); //克隆网格模型
// this.scene.add(meshs);
// obj.position.y = 80;
// // console.log(this.meshs);
// if (JSON.stringify(this.meshs) !== "{}") {
// // console.log(1);
// // console.log(this.meshs);
// // console.log(obj);
// if (this.meshs == obj) {
// console.log("相等");
// this.mesh = this.meshs.clone(); //克隆网格模型
// this.scene.add(this.mesh);
// obj.position.y = 80;
// } else {
// console.log("!=");
// // this.scene.remove(this.meshs)
// }
// } else {
// // console.log(2);
// this.meshs = obj;
// }
// intersects[ 0 ].object.material.color.set( 0xff0000 );
}
});
if (num === 0 || num) {
let obj = this.objs[num];
// 位置拆分;
obj.execute = !obj.execute;
this.obj = obj;
// 删除
helper.setFromObject(obj);
// helper.visible 辅助线
// helper.visible = false;
if (obj.children[0].material.length) {
obj.children[0].material.forEach((item) => {
// item.color.set("#ff0000")
});
} else {
// obj.children[0].material.color.set("#ff0000")
}
}
},
// 加载模型
loadObj(num) {
num = num || 0;
if (this.models.length <= num) {
this.light();
this.animate();
this.loading.close();
this.$emit('finish')
// console.log(this.$store.state.objx,"store");
// this.$bus.$on('tests', os => {
// console.log(os,"bus");
// this.autoTransform(os);
// })
return
};
let name = this.models[num].id;
// console.log(name, "测试");
if (!this.manager) {
this.manager = new THREE.LoadingManager();
this.manager.addHandler(/\.dds$/i, new DDSLoader());
}
let mtl = new MTLLoader(this.manager);
let objLoad = new OBJLoader(this.manager);
mtl.setPath("./static/model/");
objLoad.setPath("./static/model/");
mtl.load(name + ".mtl", (materials) => {
materials.preload();
objLoad.setMaterials(materials);
objLoad.load(name + ".obj", (obj) => {
obj.scale.set(0.05, 0.05, 0.05);
obj.position.set(100, -40, 0);
obj.receiveShadow = true;
this.objs[num] = obj;
this.objs.map((item, index) => {
this.models.find((val, key) => {
if (index == key) {
(item.title = val.title),
(item.tempera = val.tempera);
item.ids = val.id;
item.execute = val.execute;
item.color = val.color;
}
});
});
this.scene.add(this.objs[num]);
this.loadObj(num + 1);
});
});
this.loading = this.$loading({
lock: true,
text: "模型加载中...",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
},
// 灯光效果
light() {
// console.log(this.objs);
let light = new THREE.DirectionalLight(0xdfebff, 0.45);
light.position.set(20, 10, 50);
light.position.multiplyScalar(0.3);
this.scene.add(light);
let light2 = new THREE.DirectionalLight(0xdfebff, 0.45);
light2.position.set(-15, -10, 0);
light2.position.multiplyScalar(0.3);
this.scene.add(light2);
//添加环境光
let ambientLight = new THREE.AmbientLight("0xFFFFFF");
this.scene.add(ambientLight);
},
mousemove(event) {
this.pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
this.pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
},
// 动画效果
animate() {
this.handle = requestAnimationFrame(this.animate);
this.renderer.render(this.scene, this.camera);
if (this.composer) {
this.composer.render();
}
// this.test();
},
// outlineObj(selectedObjects,status) {
// // 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。
// this.composer = new EffectComposer(this.renderer);
// // 新建一个场景通道 为了覆盖到原理来的场景上
// this.renderPass = new RenderPass(this.scene, this.camera);
// this.composer.addPass(this.renderPass);
// // 物体边缘发光通道
// this.outlinePass = new OutlinePass(
// new THREE.Vector2(window.innerWidth, window.innerHeight),
// this.scene,
// this.camera,
// selectedObjects
// );
// this.outlinePass.selectedObjects = selectedObjects;
// this.outlinePass.edgeStrength = 10.0; // 边框的亮度
// this.outlinePass.edgeGlow = 1; // 光晕[0,1]
// this.outlinePass.usePatternTexture = false; // 是否使用父级的材质
// this.outlinePass.edgeThickness = 1.0; // 边框宽度
// this.outlinePass.downSampleRatio = 1; // 边框弯曲度
// this.outlinePass.pulsePeriod = 5; // 呼吸闪烁的速度
// if(!status) {
// this.outlinePass.visibleEdgeColor.set(parseInt(0xff0000))
// } else {
// this.outlinePass.visibleEdgeColor.set(parseInt(0x00ff00)); // 呼吸显示的颜色
// }
// this.outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0); // 呼吸消失的颜色
// this.outlinePass.clear = true;
// this.composer.addPass(this.outlinePass);
// // 自定义的着色器通道 作为参数
// var effectFXAA = new ShaderPass(FXAAShader);
// effectFXAA.uniforms.resolution.value.set(
// 1 / window.innerWidth,
// 1 / window.innerHeight
// );
// effectFXAA.renderToScreen = true;
// this.composer.addPass(effectFXAA);
// this.outlinePass = null
// selectedObjects = null
// this.outlinePass.forEach((item) => {
// if (item.children.length) {
// removeObj(item);
// } else {
// clearCache(item);
// item.clear();
// }
// });
// this.outlinePass = null
// selectedObjects.clear();
// this.selectedObjects = null;
// },
autoTransform(newName) {
console.log(newName,"bus");
if (this.clone_obj) {
this.scene.remove(this.clone_obj);
this.watch_num += 1;
}else{
return
}
if (this.objs) {
this.objs.forEach((item, index) => {
// 遍历他们两个对象的名称是否相等
if (item.ids == newName.designation ) {
// 将传过来的成功失败标识复制给objs
item.status = newName.status;
// 如果等于0 代表成功
if (item.status == 0) {
// 克隆
this.clone_obj = item.clone();
// 添加材质
let materials = [];
if (this.clone_obj.children[0].material.length) {
this.clone_obj.children[0].material.forEach(
() => {
// 添加材质
materials.push(
new THREE.MeshPhongMaterial({
color: 0xff0000,
transparent: true,
opacity: 0.6,
})
);
this.clone_obj.children[0].material =
materials; // clone_obj.position.set(0, 0, 0);
// 添加场景
this.scene.add(this.clone_obj);
if (this.watch_num == 4) {
setTimeout(() => {
if (this.clone_obj)
this.scene.remove(
this.clone_obj
);
}, 2000);
}
}
);
} else {
this.clone_obj.children[0].material =
new THREE.MeshPhongMaterial({
color: 0xff0000,
transparent: true,
opacity: 0.6,
});
this.scene.add(this.clone_obj);
if (this.watch_num == 4) {
setTimeout(() => {
if (this.clone_obj)
this.scene.remove(this.clone_obj);
}, 2000);
}
}
// 克隆添加材质
} else {
if (item.children[0].material.length) {
item.children[0].material.forEach((item) => {
// 添加材质
item.color.set("#33001a");
});
} else {
item.children[0].material.color.set("#33001a");
}
}
}
});
}
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.three_check_container {
position: relative;
}
.is-auto {
position: absolute;
bottom: 50px;
left: 13px;
}
.manual {
width: 40px;
padding: 5px;
background: rgba(255, 255, 255, 0.5);
z-index: 20;
border: 1px solid #fff;
text-align: center;
font-weight: bold;
}
</style>