Compare commits

..

2 Commits

@ -4,7 +4,7 @@
<!-- <VueThreeMachine /> -->
<!-- <vueThreeEquipment /> -->
<!-- <VueGradeGauge /> -->
<!-- <StompDemo />-->
<!-- <StompDemo /> -->
<el-config-provider :locale="zhCn">
<router-view />
</el-config-provider>
@ -19,7 +19,7 @@ import viewIndex from '@/layout/view_index.vue';
import zhCn from 'element-plus/es/locale/lang/zh-cn';
// xq
// F:\vue\workspace\maotu-webtopo\src\components\StompDemo.vue
import StompDemo from '@/components/StompDemo.vue';
// import StompDemo from '@/components/StompDemo.vue';
import VueMyTest from '@/components/my-test.vue';
import VueMyButton from '@/components/my-button.vue';
@ -197,6 +197,11 @@ leftAsideStore.registerConfig('vue四遥组件', [
val: '',
title: '绑定ID'
},
showInfo: {
type: 'switch',
val: true,
title: '显示详情'
},
location: {
type: 'select',
val: 'bottom',
@ -476,6 +481,12 @@ leftAsideStore.registerConfig('vue公共组件', [
type: 'switch',
val: true,
title: '辅助框'
},
testStr: {
type: 'map',
val: {},
title: '测试',
disabled: true
}
}
},

Binary file not shown.

@ -10,7 +10,8 @@ export type ILeftAsideConfigItemPublicPropsType =
| 'upload'
| 'inputSelectId'
| 'inputTypeTag' //inputTypeTag 必须和 inputSelectId 一起使用
| 'inputSelectImgId';
| 'inputSelectImgId'
| 'map'; //使用这个类型 disabled必须为true(必须隐藏)
// 开放注册配置
export type ILeftAsideConfigItemPublicProps = Record<
string,

@ -13,7 +13,7 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
//threejs
// threejs
import {
AxesHelper,
Color,
@ -87,44 +87,51 @@ loader.setDRACOLoader(dracoLoader);
let meshArr: Group[] = [];
// public\models\nitrogenInjection\nitrogenInjection.gltf
loader.load('/models/substation/substation.gltf', (gltf: any) => {
//
loadedModel = gltf.scene;
scene.add(gltf.scene);
const loadTime = Date.now() - startTime;
//
controls.update();
// controls.update();
render.render(scene, camera);
console.log(`大场景模型已加载并显示,总耗时:${loadTime}ms`);
loading.value = false;
});
//
const ambientLight = new AmbientLight('#ffffff', 1.2); // 0.6 1.0
scene.add(ambientLight);
//
const directionalLight = new DirectionalLight('#ffffff', 1.4); // 0.2 0.8
scene.add(directionalLight);
directionalLight.position.set(20, 20, 10);
// //
const pointLight = new PointLight('#ffffff', 1.4, 1800); // 0.5 1.0
scene.add(pointLight);
pointLight.position.set(0, 40, 0);
// //
// const rgbELoader = new RGBELoader().load(
// '/models/texture/Alex_Hart-Nature_Lab_Bones_2k.hdr',
// (envMap: any) => {
// envMap.mapping = EquirectangularReflectionMapping;
// scene.environment = envMap;
// }
// );
// //
// const ambientLight = new AmbientLight('#ffffff', 1.2); // 0.6 1.0
// scene.add(ambientLight);
// //
// const directionalLight = new DirectionalLight('#ffffff', 1.4); // 0.2 0.8
// scene.add(directionalLight);
// directionalLight.position.set(20, 20, 10);
// // //
// const pointLight = new PointLight('#ffffff', 1.4, 1800); // 0.5 1.0
// scene.add(pointLight);
// pointLight.position.set(0, 40, 0);
// 便
const rgbELoader = new RGBELoader().load(
'/models/texture/Alex_Hart-Nature_Lab_Bones_2k.hdr',
(envMap: any) => {
envMap.mapping = EquirectangularReflectionMapping;
scene.environment = envMap;
envMapTexture = envMap; //
}
);
//
const timeline1 = gsap.timeline();
const timeline2 = gsap.timeline();
// 便
let loadedModel: any = null;
let envMapTexture: any = null;
//
function tranlate(position: Vector3, target: Vector3) {
timeline1.to(camera.position, {
@ -191,11 +198,98 @@ onMounted(() => {
});
onUnmounted(() => {
//
console.log('开始清理 Three.js 资源...');
// 1.
// requestAnimationFrame
// 2. ResizeObserver
if ((window as any)._resizeObserver) {
(window as any)._resizeObserver.disconnect();
delete (window as any)._resizeObserver;
}
// 3. GSAP
timeline1.pause();
timeline1.clear();
timeline2.pause();
timeline2.clear();
gsap.globalTimeline.clear();
// 4. DOM
if (div3D.value && render.domElement.parentNode === div3D.value) {
div3D.value.removeChild(render.domElement);
}
// 5.
controls.dispose();
// 6.
if (loadedModel) {
loadedModel.traverse((child: any) => {
if (child.isMesh) {
//
if (child.geometry) {
child.geometry.dispose();
}
//
if (child.material) {
const materials = Array.isArray(child.material) ? child.material : [child.material];
materials.forEach((material: any) => {
//
[
'map',
'normalMap',
'roughnessMap',
'metalnessMap',
'emissiveMap',
'aoMap',
'displacementMap'
].forEach((key) => {
if (material[key]) {
material[key].dispose();
}
});
//
material.dispose();
});
}
}
});
//
scene.remove(loadedModel);
}
// 7.
if (envMapTexture) {
envMapTexture.dispose();
}
// 8.
scene.traverse((child: any) => {
if (child.isLight) {
child.dispose();
}
});
// 9.
while (scene.children.length > 0) {
scene.remove(scene.children[0]);
}
// 10.
render.dispose();
render.forceContextLoss();
render.domElement.remove();
// 11.
scene.clear();
console.log('Three.js 资源清理完成');
});
</script>
@ -215,6 +309,7 @@ onUnmounted(() => {
top: 50%;
left: 2%;
transform: translateY(-50%); /* 垂直居中 */
transform: translateZ(0);
display: flex;
flex-direction: column;
gap: 20px;

@ -77,15 +77,18 @@ scene.add(camera);
//
const render = new WebGLRenderer({
antialias: false, // 齿
powerPreference: 'high-performance', // 使GPU
stencil: false, //
antialias: true, // 齿
powerPreference: 'high-performance',
stencil: false,
depth: true,
logarithmicDepthBuffer: true //
logarithmicDepthBuffer: true,
precision: 'mediump' // 使
});
render.setClearColor(new Color('#131519'));
render.setPixelRatio(Math.min(window.devicePixelRatio, 2)); //
//
render.shadowMap.enabled = false; //
render.shadowMap.enabled = false;
render.shadowMap.autoUpdate = false; //
//
const controls = new OrbitControls(camera, render.domElement);
@ -94,15 +97,14 @@ const controls = new OrbitControls(camera, render.domElement);
// controls.autoRotate = false;
// controls.enablePan = false; //
controls.autoRotateSpeed = 1;
controls.dampingFactor = 0.2;
controls.rotateSpeed = 0.3; // 1.0
controls.enableDamping = true;
controls.dampingFactor = 0.05; //
controls.rotateSpeed = 0.5; //
controls.enableDamping = false; //
controls.enableRotate = true;
controls.minDistance = 1; //
// 4545
// 4545
controls.minPolarAngle = Math.PI / 4; // 45 (π/4)
controls.maxPolarAngle = (Math.PI * 3) / 4; // 45 (3π/4)
controls.minDistance = 1;
//
controls.minPolarAngle = Math.PI / 4;
controls.maxPolarAngle = (Math.PI * 3) / 4;
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
@ -137,15 +139,28 @@ loader.load(
async (gltf: any) => {
console.log('文件下载完成,开始解析模型...');
//
//
const mergedMeshes: any[] = [];
gltf.scene.traverse((child: any) => {
if (child.isMesh) {
//
child.frustumCulled = true; //
child.frustumCulled = true;
if (child.material) {
//
child.material.side = 0; // FrontSide -
child.material.side = 0;
child.material.needsUpdate = true;
//
if (child.material.map) {
child.material.map.minFilter = THREE.LinearMipMapLinearFilter;
child.material.map.magFilter = THREE.LinearFilter;
}
}
// 使
mergedMeshes.push(child);
}
});
@ -160,7 +175,8 @@ loader.load(
}
const loadTime = Date.now() - startTime;
console.log(`大场景模型完全加载并显示,总耗时: ${loadTime}ms`);
console.log(`大场景模型完全加载并显示,总耗时:${loadTime}ms`);
console.log(`模型网格数量:${mergedMeshes.length}`);
},
//
(xhr) => {
@ -188,14 +204,17 @@ nextTick(() => {
}
});
//
const rgbELoader = new RGBELoader().load(
'/models/texture/Alex_Hart-Nature_Lab_Bones_2k.hdr',
(envMap: any) => {
envMap.mapping = EquirectangularReflectionMapping;
scene.environment = envMap;
}
);
//
setTimeout(() => {
const rgbELoader = new RGBELoader().load(
'/models/texture/Alex_Hart-Nature_Lab_Bones_2k.hdr',
(envMap: any) => {
envMap.mapping = EquirectangularReflectionMapping;
scene.environment = envMap;
console.log('环境贴图加载完成');
}
);
}, 500); // 500ms
//
const timeline1 = gsap.timeline();
@ -242,7 +261,8 @@ function handleResize() {
function init() {
requestAnimationFrame(init);
controls.update();
//
// controls.update(); //
render.render(scene, camera);
}

@ -1,4 +1,5 @@
<template>
<!-- <el-button @click="ccc">Default</el-button> -->
<el-card class="card">
<el-scrollbar height="100%">
<h2 class="cardHead">运行信息</h2>
@ -182,6 +183,7 @@
</template>
<script lang="ts" setup>
import { ElButton } from 'element-plus';
import { computed, ref, watch, onMounted } from 'vue';
let dialogTableVisible = ref(false);
@ -210,9 +212,22 @@ const props = defineProps({
isSwitch: {
type: Boolean,
default: true
},
testStr: {
type: String,
default: ''
},
definitionItemJson: {
type: Object as any,
default: () => ({})
}
});
console.log('传递:', props.definitionItemJson);
function ccc() {
props.definitionItemJson.props.testStr = 'aaaaaa';
}
const activities = [
{
content: '灭火允许',

@ -1,87 +1,5 @@
<template>
<!-- 四遥遥信 -->
<!-- <div style="display: flex; gap: 10px; align-items: center">
<el-popover
:width="300"
popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;"
>
<template #reference>
<el-icon
:class="['iconStyle', isAalarm ? 'blink-animation' : '']"
:size="22"
:style="{ color: isBool ? 'rgb(146, 252, 40)' : 'rgb(252, 40, 40)' }"
>
<WarningFilled />
</el-icon>
</template>
<template #default>
<div class="demo-rich-conent" style="display: flex; gap: 20px; flex-direction: column">
<el-icon
class="iconStyle"
:size="60"
:style="{ color: isBool ? 'rgb(146, 252, 40)' : 'rgb(252, 40, 40)' }"
>
<WarningFilled />
</el-icon>
<el-row :gutter="6">
<el-col :span="12" :xs="24" :sm="12" :md="6" class="elColInfo">
<el-statistic title="绑定ID" :value="null">
<template #suffix>
<el-tag size="default" type="primary">{{ moduleId }}</el-tag>
</template>
</el-statistic>
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="12" class="elColInfo">
<el-statistic title="节点名称" :value="null">
<template #suffix>
<el-tag size="default" type="success">{{ modeName }}</el-tag>
</template>
</el-statistic>
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="6" class="elColInfo">
<el-statistic title="类型" :value="null">
<template #suffix>
<el-tag size="default" type="primary">遥信</el-tag>
</template>
</el-statistic>
</el-col>
</el-row>
<el-row :gutter="6">
<el-col :span="12" :xs="24" :sm="12" :md="6" class="elColInfo">
<el-statistic title="开关情况" :value="null">
<template #suffix>
<el-tag size="default" type="primary">{{ isBool }}</el-tag>
</template>
</el-statistic>
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="12" class="elColInfo">
<el-statistic title="告警" :value="null">
<template #suffix>
<el-tag size="default" type="primary">{{ isAalarm }}</el-tag>
</template>
</el-statistic>
</el-col>
<el-col :span="12" :xs="24" :sm="12" :md="6" class="elColInfo">
<el-statistic title="是否可告警" :value="null">
<template #suffix>
<el-tag size="default" type="primary">{{ isAlarmable }}</el-tag>
</template>
</el-statistic>
</el-col>
</el-row>
</div>
</template>
</el-popover>
<el-tag type="primary">{{ modeName }}</el-tag>
</div> -->
<!-- <button @click="console.log('data:', nodeByModelsStore.nodeMap)">点击</button> -->
<el-row v-if="location === 'top'">
<el-col :span="24" class="flex-center">
@ -106,7 +24,7 @@
<div style="display: flex; gap: 10px; align-items: center">
<el-popover
:width="300"
:disabled="false"
:disabled="showInfo"
popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;"
>
<!-- :style="{ color: isBool ? 'rgb(146, 252, 40)' : 'rgb(252, 40, 40)' }" -->
@ -226,7 +144,6 @@ onUnmounted(() => {
emitter.off(props.definitionItemJson.id);
});
// const props = defineProps(['definitionItemJson']);
const props = defineProps({
moduleType: {
@ -241,6 +158,10 @@ const props = defineProps({
type: Object,
default: () => ({})
},
showInfo: {
type: Boolean,
default: false
},
location: {
type: String,
default: 'bottom'
@ -286,24 +207,6 @@ function loadingModuleById() {
}
}
// function loadingModuleById() {
// const globalData = (window as any).globalData as Map<string, any>;
// if (
// props.moduleId !== '' &&
// props.moduleId !== undefined &&
// props.moduleId !== '--' &&
// globalData?.has(props.moduleId)
// ) {
// let module = globalData.get(props.moduleId);
// if (module) {
// modeName.value = module.node.name;
// isBool.value = module.double == 1;
// isAalarm.value = module.alarm;
// isAlarmable.value = module.alarmable;
// }
// }
// }
//
emitter.on(props.definitionItemJson.id, (value) => {
console.log('触发事件', value);

Loading…
Cancel
Save