factory_web/src/views/bigScreen/index_enp_blue.vue

1645 lines
53 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="dashboard">
<header>
<div class="headerImg">
<img src="img/enp_blue/header_enp.png" style="width:100%;">
<div class="sysName">
水泥有限公司</div>
</div>
<div class="login_config" style="z-index:1000;position: absolute;right: 1vw;bottom: 0;">
<el-button :icon="config.dark ? 'el-icon-sunny' : 'el-icon-moon'" circle type="info"
@click="configDark"></el-button>
</div>
<div style="position: absolute;top:1.3vh;height:6vh">
<div style="display: flex;padding-top: 1vh;margin-left: 1vw;">
<div :class="bindClass(0)" @click="menuClick(0)">
<div class="menuItem">首页</div>
</div>
<div :class="bindClass(1)">
<div class="menuItem">
<el-dropdown class="dropdown" trigger="click" @command="handleClick">
<span class="el-dropdown-link">
有组织排放管理
</span>
<template #dropdown>
<el-dropdown-menu class="enpMenu">
<el-dropdown-item command="paikou">排放口清单</el-dropdown-item>
<el-dropdown-item command="cems">CEMS监测清单</el-dropdown-item>
<el-dropdown-item command="cems2">CEMS监测预警</el-dropdown-item>
<el-dropdown-item command="cemsExport">CEMS报表导出</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div :class="bindClass(2)">
<div class="menuItem">
<el-dropdown class="dropdown" trigger="click" @command="handleClick2">
<span class="el-dropdown-link">
无组织排放管理
</span>
<template #dropdown>
<el-dropdown-menu class="enpMenu">
<el-dropdown-item command="pollutant">污染源清单</el-dropdown-item>
<el-dropdown-item command="pollutant2">污染源监测</el-dropdown-item>
<el-dropdown-item command="smartg">智能治理</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</div>
</div>
<div style="position: absolute;top:1.3vh;right: 8px;height: 6vh;">
<div style="display: flex;padding-top: 1vh;padding-right: 1vw;justify-content: flex-end;">
<div :class="bindClass(3)">
<div class="menuItem">
<el-dropdown class="dropdown" trigger="click" @command="handleClick3">
<span class="el-dropdown-link">
清洁运输
</span>
<template #dropdown>
<el-dropdown-menu class="enpMenu">
<el-dropdown-item command="transport">厂外运输</el-dropdown-item>
<el-dropdown-item command="innerClean">厂内清洁</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div :class="bindClass(4)" @click="menuClick(4)">
<!-- <div class="menuItem">环保管理</div> -->
<div class="menuItem">
<el-dropdown class="dropdown" trigger="click" @command="handleClick4">
<span class="el-dropdown-link">
环保管理
</span>
<template #dropdown>
<el-dropdown-menu class="enpMenu">
<el-dropdown-item command="envirqualmonitor">环境质量监测</el-dropdown-item>
<el-dropdown-item command="envirmonitor">环境监测清单</el-dropdown-item>
<!-- <el-dropdown-item command="pollutecalendar">污染日历</el-dropdown-item> -->
<!-- <el-dropdown-item command="">决策分析</el-dropdown-item> -->
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div :class="bindClass(5)" @click="menuClick(5)">
<!-- <div class="menuItem">台账管理</div> -->
<div class="menuItem">
<el-dropdown class="dropdown" trigger="click" @command="handleClick4">
<span class="el-dropdown-link">
台账管理
</span>
<template #dropdown>
<el-dropdown-menu class="enpMenu">
<el-dropdown-item command="eqments">设备清单</el-dropdown-item>
<el-dropdown-item command="alarmrecord">报警记录 </el-dropdown-item>
<el-dropdown-item command="video">视屏墙 </el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div class="wraning_icon"></div>
<div class="user_icon" @click="backSystem"></div>
</div>
</div>
</header>
<el-main style="padding:0;overflow: hidden;">
<div v-show="activeIndex == 0" class="model">
<div id="loadingScreen">
<el-progress type="circle" :percentage="loadedPercent" :width=220 status="warning">
<template #default="{ percentage }">
<div style="font-size: 30px; color: white; font-weight: bold">{{ percentage }}%</div>
<div style="font-size: 18px; color: white; margin-top: 10px">工厂模型加载中</div>
</template>
</el-progress>
</div>
<canvas id="renderCanvas"></canvas>
</div>
<!-- 左侧列表数据 -->
<div v-show="activeIndex == 0" class="left_other animate__animated animate__backInLeft">
<!-- 无组织污染源一览 -->
<div class="panel panel1">
<div class="blockTitle">
<div class="blockTitleText">无组织污染源一览</div>
<img class="blockTitleImg" src="img/enp_blue/block_title.png">
</div>
<div style="display: flex;">
<div style="padding:0.5vw">
<div class="chart" id="chart1" style="width:7vw;height:7vw;"></div>
</div>
<div style="width: 60%;">
<div class="pieDataItem">
<div class="pieDataText">粉状物料输送</div>
<div class="pieDataNumber">51</div>
</div>
<div class="pieDataItem">
<div class="pieDataText">生产工艺过程</div>
<div class="pieDataNumber">2</div>
</div>
<div class="pieDataItem">
<div class="pieDataText">物料储存</div>
<div class="pieDataNumber">19</div>
</div>
<div class="pieDataItem">
<div class="pieDataText">物料输送</div>
<div class="pieDataNumber">102</div>
</div>
</div>
</div>
</div>
<!-- 接入设备数量总览 -->
<div class="panel panel2">
<div class="blockTitle">
<div class="blockTitleText">接入设备数量总览</div>
<img class="blockTitleImg" src="img/enp_blue/block_title.png">
</div>
<div style="display: flex;padding: 1vh 1vw;">
<div style="width: 50%;">
<div class="eqItem">
<img class="eqImg" src="img/enp_blue/eq_s.svg">
<div class="eqText">
<div class="eqName">生产设备</div>
<div class="eqNumWrap"><span class="eqNum">34</span>台</div>
</div>
</div>
<div class="eqItem">
<img class="eqImg" src="img/enp_blue/eq_v.svg">
<div class="eqText">
<div class="eqName">监测设备</div>
<div class="eqNumWrap"><span class="eqNum">9</span>台</div>
</div>
</div>
</div>
<div style="width: 50%;">
<div class="eqItem">
<img class="eqImg eqImg_s" src="img/enp_blue/eq_z.svg">
<div class="eqText eqText_s">
<div class="eqName">治理设备</div>
<div class="eqNumWrap"><span class="eqNum">44</span>台</div>
</div>
</div>
<div class="eqItem">
<img class="eqImg eqImg_s" src="img/enp_blue/eq_c.svg">
<div class="eqText eqText_s">
<div class="eqName">监控设备</div>
<div class="eqNumWrap"><span class="eqNum">20</span>台</div>
</div>
</div>
<div class="eqItem">
<img class="eqImg eqImg_s" src="img/enp_blue/hjzljc.svg">
<div class="eqText eqText_s">
<div class="eqName">环境质量检测</div>
<div class="eqNumWrap"><span class="eqNum">9</span>台</div>
</div>
</div>
</div>
</div>
</div>
<!-- 主要排放口实时监测清单 -->
<div class="panel panel3">
<div class="blockTitle">
<div class="blockTitleText">主要排放口实时监测清单</div>
<img class="blockTitleImg" src="img/enp_blue/block_title.png">
</div>
<div>
<div class="title_s">水泥磨机排气筒</div>
<div class="status"><span style="color:#32D74B">数据正常</span><span>2024-01-26 14:32:06</span></div>
<div class="tableHear" style="padding: 0 1vh;">
<div style="flex:1;height:1vh"></div>
<div style="flex:5;margin: 0 1vh;">项目</div>
<div style="flex:2">实测</div>
<div style="flex:2">折算</div>
</div>
<div class="rowItem">
<div class="rowindex">1</div>
<div class="rowname">颗粒物(mg/m³)</div>
<div class="rownum">1</div>
</div>
<div class="rowItem">
<div class="rowindex">2</div>
<div class="rowname">SO₂(mg/m³)</div>
<div class="rownum">2</div>
</div>
<div class="rowItem">
<div class="rowindex">3</div>
<div class="rowname">NOx(mg/m³)</div>
<div class="rownum">3</div>
</div>
</div>
</div>
</div>
<!-- 右侧数据 -->
<div v-show="activeIndex == 0" class="right_other animate__animated animate__backInRight">
<!-- 统计 -->
<div class="panel panel4" style="box-sizing:border-box;padding:0 1vh">
<div class="right_one">
<div class="leftNumbers">
<div class="numberItem">
<div class="numberItemName">含氧量</div>
<div><span class="numberItemNum">1.56</span><span class="numberItemUnit">%</span></div>
</div>
<div class="numberItem">
<div class="numberItemName">温度</div>
<div><span class="numberItemNum">73.5</span><span class="numberItemUnit">℃</span></div>
</div>
<div class="numberItem">
<div class="numberItemName">流速</div>
<div><span class="numberItemNum">4.185</span><span class="numberItemUnit">m/s</span></div>
</div>
</div>
<div class="rightNumbers">
<div class="numberItem">
<div class="numberItemName">压力</div>
<div><span class="numberItemNum">721.215 </span><span class="numberItemUnit">KPa</span></div>
</div>
<div class="numberItem">
<div class="numberItemName">湿度</div>
<div><span class="numberItemNum">3.615 </span><span class="numberItemUnit">%RH</span> </div>
</div>
<div class="numberItem">
<div class="numberItemName">流量</div>
<div>-</div>
</div>
</div>
<div class="ballImg">
<span class="right_one_status">正常</span>
</div>
</div>
</div>
<!-- 环境质量实时监测清单 -->
<div class="panel panel_big panel5">
<div class="blockTitle">
<div class="blockTitleText">环境质量实时监测清单</div>
<img class="blockTitleImg" src="img/enp_blue/block_title.png">
</div>
<div>
<div class="tableHear" style="margin-top:1vh;height:2.6vh;line-height:2.6vh;display:flex;padding:1vh">
<div style="flex:2">项目</div>
<div style="flex:1">PM10(μg/m³)</div>
<div style="flex:1">PM2.5(μg/m³)</div>
</div>
<div class="tableBody">
<div v-for="item in wData" :key="item">
<div class="badyItem">
<div style="flex:2">
<img src="img/enp_blue/listImg.png"
style="width:2vh;height:2vh;margin:1.2vh 1vh;vertical-align:middle">
<span>{{ item.name }}</span>
</div>
<span style="flex:1">{{ item.pm10 }}</span>
<span style="flex:1">{{ item.pm25 }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-show="activeIndex == 0" class="left_border"></div>
<div v-show="activeIndex == 0" class="right_border"></div>
<div v-show="activeIndex == 0" class="btns_enp">
<div class="btns" :class="bindBtnClass(0)">生产设备</div>
<div class="btns" :class="bindBtnClass(1)">治理设备</div>
<div class="btns" :class="bindBtnClass(2)">监测设备</div>
<div class="btns" :class="bindBtnClass(3)">监控设备</div>
<div class="btns" :class="bindBtnClass(4)">环境监测</div>
</div>
<div v-show="activeIndex == 0" class="bottom_enp"></div>
<div v-if="activeIndex != 0" class="container">
<el-drawer v-model="elDrawer" :modal="false" :close-on-click-modal="false" size="95%" :with-header="false"
direction="ltr" :show-close="false" id="enpElDrawer">
<!-- <div class="sysName">智能环保一体化管控平台</div> -->
<org-dialog v-if="activeDrawerName == 'paikou'" @close="closeDialog"></org-dialog>
<cems-drawer v-else-if="activeDrawerName == 'cems'" @close="closeDialog"></cems-drawer>
<cems2-drawer v-else-if="activeDrawerName == 'cems2'" @close="closeDialog"></cems2-drawer>
<cems-export v-else-if="activeDrawerName == 'cemsExport'" @close="closeDialog"></cems-export>
<pollutant v-else-if="activeDrawerName == 'pollutant'" @close="closeDialog"></pollutant>
<!-- 运输清洁 -->
<transport v-else-if="activeDrawerName == 'transport'" @close="closeDialog"></transport>
<innerclean v-else-if="activeDrawerName == 'innerClean'" @close="closeDialog"></innerclean>
<!-- 环保管理 -->
<envirqualmonitor v-else-if="activeDrawerName == 'envirqualmonitor'" @close="closeDialog"></envirqualmonitor>
<envirmonitor v-else-if="activeDrawerName == 'envirmonitor'" @close="closeDialog"></envirmonitor>
<pollutecalendar v-else-if="activeDrawerName == 'pollutecalendar'" @close="closeDialog"></pollutecalendar>
<!-- 台账管理 -->
<eqments v-else-if="activeDrawerName == 'eqments'" @close="closeDialog"></eqments>
<alarmrecord v-else-if="activeDrawerName == 'alarmrecord'" @close="closeDialog"></alarmrecord>
<pollutant2 v-else-if="activeDrawerName == 'pollutant2'" @close="closeDialog"></pollutant2>
<smartg v-else-if="activeDrawerName == 'smartg'" @close="closeDialog"></smartg>
<videowall v-else-if="activeDrawerName == 'video'" @close="closeDialog"></videowall>
</el-drawer>
</div>
</el-main>
</div>
</template>
<script>
import * as echarts from "echarts";
import * as BABYLON from "babylonjs"
import * as BABYLON_GUI from "babylonjs-gui"
import * as BABYLON_GRID from "@/utils/gridMaterial"
import * as BABYLON_MATERIAL from "@/utils/babylonMaterial"
import orgDialog from "./enpComponents/orgwryList"
import cemsDrawer from './enpComponents/cems.vue'
import cems2Drawer from './enpComponents/cems2.vue'
import cemsExport from './enpComponents/cemsExport.vue'
import pollutant from "./enpComponents/pollutant.vue"
import innerclean from "./enpComponents/innerclean.vue"
import transport from "./enpComponents/transport.vue";
import envirqualmonitor from "./enpComponents/envirqualmonitor.vue";
import envirmonitor from "./enpComponents/envirmonitor.vue";
import pollutecalendar from "./enpComponents/pollutecalendar.vue";
import eqments from "./enpComponents/eqments.vue";//台账
import alarmrecord from "./enpComponents/alarmrecord.vue";
import pollutant2 from "./enpComponents/pollutant2.vue"
import smartg from "./enpComponents/smartg.vue";
import videowall from "./enpComponents/video.vue";
import 'babylonjs-loaders';
import 'animate.css';
export default {
components: {
orgDialog,
cemsDrawer,
cems2Drawer,
cemsExport,
pollutant,
innerclean,
transport,
envirqualmonitor,
envirmonitor,
pollutecalendar,
eqments,
alarmrecord,
pollutant2,
smartg,
videowall
},
data() {
return {
config: {
dark: this.$TOOL.data.get('APP_DARK') || false
},
elDrawer: true,
isCollapse: false,
nowDay: 1,
initialAlpha: -Math.PI / 0.89,
initialBeta: Math.PI / 3.3,
initialRadius: 18,
initialTarget: null,
scene: null,
myui: null,
is_mainviewpoint: false,
resizeTimeout: null,
engine: null,
loadedPercent: 0,
sectionNames: {
"干渣库_primitive0": "电石渣",
"原料磨及废气处理_primitive0": "原料磨",
"窑": "回转窑",
"煤粉制备_primitive1": "煤磨",
"水泥磨房_primitive0": "水泥磨",
"水泥储存及散装库_primitive2": "水泥包装",
// "停车场": "停车场"
},
showKgcet: true,
currentLightMesh: null,
activeBtns: 0,
activeDrawerName: '',
activeIndex: 0,
activeSection: 2,
activeSectionName: '回转窑',
updateTime: '2023-08-17 16:00:00',
pieOption: {
backgroundColor: 'rgba(255,255,255,0)',
color: ['rgb(3,195,198)', 'rgb(155,248,249)', 'rgb(110,181,249)', 'rgb(205,248,248)'],
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
series: {
name: '无组织污染源',
type: 'pie',
radius: [35, 40],
center: ['50%', '50%'],
emphasis: {
focus: 'series',
label: {
show: true,
fontSize: 10,
fontWeight: 'bold'
}
},
label: {
show: false,
position: 'center'
},
labelLine: {
show: false
},
data: [],
},
},
ws: null,
pieData: [
{ value: 51, name: '粉状物料输送' },
{ value: 2, name: '生产工艺过程' },
{ value: 19, name: '物料储存' },
{ value: 102, name: '物料输送' },
],
eqNumData: [
{ value: 34, name: '生产设备' },
{ value: 44, name: '治理设备' },
{ value: 9, name: '监测设备' },
{ value: 20, name: '监控设备' },
{ value: 9, name: '环境质量检测' },
],
monitorData: [
{ value: 1.167, name: '颗粒物(mg/m³)' },
{ value: 5.714, name: 'SO₂(mg/m³)' },
{ value: 12.546, name: 'NOx(mg/m³)' },
],
arguData: [
{ value: 21.215, name: '含氧量' },
{ value: 78.318, name: '温度' },
{ value: 4.183, name: '流速' },
{ value: 21.215, name: '压力' },
{ value: 3.612, name: '湿度' },
{ value: 2, name: '流量' },
],
mgroupValues: {
电石渣: { total: '0', elec: '0' },
原料磨: { total: '0', elec: '0' },
煤磨: { total: '0', elec: '0' },
回转窑: { total: '0', elec: '0' },
水泥磨: { total: '0', elec: '0' },
水泥包装: { total: '0', elec: '0' }
},
wData: [
{ name: '磅房', pm10: '2.9', pm25: '14.2' },
{ name: '北厂界', pm10: '-', pm25: '68.1' },
{ name: '东厂界', pm10: '-', pm25: '41.322' },
],
}
},
watch: {
'config.dark'(val) {
if (val) {
document.documentElement.classList.add("dark")
this.$TOOL.data.set("APP_DARK", val)
} else {
document.documentElement.classList.remove("dark")
this.$TOOL.data.remove("APP_DARK")
}
},
'config.lang'(val) {
this.$i18n.locale = val
this.$TOOL.data.set("APP_LANG", val)
}
},
mounted() {
let that = this;
that.initCharts();
that.addListener();
that.initDomStyle();
that.$nextTick(() => {
setTimeout(function () {
// that.initFactory();
}, 1000);
});
},
beforeUnmount() {
// 性能优化
const canvas = document.getElementById('renderCanvas');
if (canvas) {
canvas.parentNode.removeChild(canvas);
}
},
methods: {
configDark() {
this.config.dark = this.config.dark ? false : true
},
backSystem() {
this.$router.push({ path: '/dashboard_enp' });
},
closeDialog() {
this.elDrawer = false;
this.activeIndex = 0;
},
drawerClick() {
this.elDrawer = true;
},
initDomStyle() {
// 获取窗口的总高度
var windowHeight = window.innerHeight;
var windowWidth = window.innerWidth;
// 获取目标元素
var dashboard = document.getElementsByClassName('dashboard')[0];
var left_other = document.getElementsByClassName('left_other')[0];
var right_other = document.getElementsByClassName('right_other')[0];
var model = document.getElementsByClassName('model')[0];
if (windowWidth > 960) {
dashboard.style.overflow = 'hidden';
// 设置目标元素的高度
left_other.style.position = 'absolute';
left_other.style.width = '20%';
right_other.style.position = 'absolute';
right_other.style.width = '20%';
model.style.position = 'absolute';
model.style.height = (windowHeight - 4) + 'px';
model.style.top = 0;
var chartHeight1 = (100 - 18) * 0.31 + 'vh';
var chartHeight2 = (100 - 18) * 0.37 + 'vh';
var chartHeight3 = (100 - 17) * 0.28 + 'vh';
var chartHeight4 = (100 - 17) * 0.715 + 'vh';
var charts = document.getElementsByClassName('panel')
for (var i = 0; i < charts.length; i++) {
var chart = charts[i]
switch (i) {
case 0:
chart.style.height = chartHeight1;
break;
case 1:
chart.style.height = chartHeight1;
break;
case 2:
chart.style.height = chartHeight2;
break;
case 3:
chart.style.height = chartHeight3;
break;
case 4:
chart.style.height = chartHeight4;
break;
}
chart.style.height = chartHeight;
}
}
else {
dashboard.style.overflow = 'auto';
var chartHeight = windowWidth * 0.6;
left_other.style.position = 'static';
left_other.style.width = '100%';
right_other.style.position = 'static';
right_other.style.width = '100%';
model.style.position = 'relative';
model.style.height = chartHeight;
var charts = document.getElementsByClassName('chart')
for (var i = 0; i < charts.length; i++) {
var chart = charts[i]
chart.style.height = chartHeight;
}
}
if (this.engine != null) {
this.engine.resize();
}
},
bindBtnClass(index) {
let classInfo = { btns: true, btnsActive: false };
if (index == this.activeBtns) {
classInfo.btnsActive = true;
}
return classInfo;
},
// 动态绑定Class
bindClass(index) {
let that = this;
let classInfo = { menuWrap: true, menuWrap1: false, menuWrap2: false, menuWrapActive: false };
if (index == that.activeIndex) {
classInfo.menuWrapActive = true;
}
if (index == 1 || index == 2) {
classInfo.menuWrap2 = true;
} else {
classInfo.menuWrap1 = true;
}
return classInfo
},
menuClick(index) {
if (index == 0) { this.activeIndex = index; }
//
},
handleClick(command) {
this.activeIndex = 1;
this.elDrawer = true;
this.activeDrawerName = command;
},
handleClick2(command) {
this.activeIndex = 2;
this.elDrawer = true;
this.activeDrawerName = command;
},
handleClick3(command) {
this.activeIndex = 3;
this.elDrawer = true;
this.activeDrawerName = command;
},
handleClick4(command) {
this.activeIndex = 4;
this.elDrawer = true;
this.activeDrawerName = command;
// if (command == 'video') {
// window.open('/demo/index.html', '_self')
// }
},
handleClick5(command) {
this.activeIndex = 5;
this.elDrawer = true;
this.activeDrawerName = command;
},
getMessage(msg) {
console.log(msg);
},
close() {
if (this.ws) {
this.ws.close();
this.ws = null;
console.log("socket已经关闭");
}
},
compare(property) {
return function (a, b) {
return a[property] - b[property];
}
},
initCharts() {
let that = this;
// 初始化所有表格
that.pieOption.series.data = that.pieData;
that.setChart('chart1', that.pieOption);
},
addListener() {
var that = this;
window.addEventListener('resize', function () {
// 如果已经有 resizeTimeout清除它
if (this.resizeTimeout) {
clearTimeout(this.resizeTimeout);
}
// 设置一个新的 resizeTimeout延迟调整样式
this.resizeTimeout = setTimeout(function () {
that.initDomStyle()
}, 300); // 延迟 300 毫秒,可以根据需要调整
});
},
resizeChart(name) {
// 根据name resize chart
var myChart = echarts.getInstanceByDom(document.getElementById(name));
if (myChart != undefined) {
// console.log(name + ' :resize')
myChart.resize();
}
},
setChart(name, option = null) {
// 根据name 渲染数据, option需填写否则option为模拟数据
var myChart = echarts.getInstanceByDom(document.getElementById(name));
if (myChart == undefined) {
myChart = echarts.init(document.getElementById(name), 'dark', { renderer: 'svg' });
}
if (option == null) {
option = Object.assign({}, this.pieOption)
}
setTimeout(() => {
try {
myChart.setOption(option);
} catch (error) { }
}, 500)
},
initFactory() {
var that = this;
const canvas = document.getElementById("renderCanvas"); // Get the canvas element
const engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine
BABYLON.DefaultLoadingScreen.prototype.displayLoadingUI = function () {
}
BABYLON.DefaultLoadingScreen.prototype.hideLoadingUI = function () {
document.getElementById("loadingScreen").style.display = "none";
}
engine.displayLoadingUI();
// Add your code here matching the playground format
const createScene = function () {
const scene = new BABYLON.Scene(engine);
scene.clearColor = BABYLON.Color3.Black(); //BABYLON.Color3(1, 0, 1);
const ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 100, height: 100 });
const groundMaterial = new BABYLON_GRID.GridMaterial("groundMaterial", scene);
groundMaterial.majorUnitFrequency = 5;
groundMaterial.minorUnitVisibility = 0.5;
groundMaterial.gridRatio = 2;
// groundMaterial.opacity = 0.99;
ground.material = groundMaterial;
ground.position.y = -0.1
// 加载背景图片
const backgroundImage = new BABYLON.Layer('', 'img/enp_blue/bg_enp.png', scene, true);
const camera = new BABYLON.ArcRotateCamera("camera", that.initialAlpha, that.initialBeta, that.initialRadius, new BABYLON.Vector3(0, 0, 1.2));
that.initialTarget = camera.getTarget();
camera.upperBetaLimit = Math.PI / 2.3; //无法移动到地面以下
camera.attachControl(canvas, true);
camera.maxZ = 1000; // 调整适当的值
// 相机限制
camera.lowerRadiusLimit = 6;
camera.upperRadiusLimit = 18;
// 灯光
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0));
light.intensity = 1.6;
// skybox
const skybox = BABYLON.MeshBuilder.CreateBox("skyBox", { size: 150 }, scene);
var skyboxMaterial = new BABYLON_MATERIAL.SkyMaterial("skyMaterial", scene);
skyboxMaterial.backFaceCulling = false;
skybox.material = skyboxMaterial;
/*
* Keys:
* - 1: Day
* - 2: Evening
* - 3: Increase Luminance
* - 4: Decrease Luminance
* - 5: Increase Turbidity
* - 6: Decrease Turbidity
* - 7: Move horizon to -50
* - 8: Restore horizon to 0
*/
var setSkyConfig = function (property, from, to) {
var keys = [
{ frame: 0, value: from },
{ frame: 100, value: to }
];
var animation = new BABYLON.Animation("animation", property, 100, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
animation.setKeys(keys);
scene.stopAnimation(skybox);
scene.beginDirectAnimation(skybox, [animation], 0, 100, false, 1);
};
window.addEventListener("keydown", function (evt) {
switch (evt.keyCode) {
case 49: setSkyConfig("material.inclination", skyboxMaterial.inclination, 0); break; // 1
case 50: setSkyConfig("material.inclination", skyboxMaterial.inclination, -0.5); break; // 2
case 51: setSkyConfig("material.luminance", skyboxMaterial.luminance, 0.1); break; // 3
case 52: setSkyConfig("material.luminance", skyboxMaterial.luminance, 1.0); break; // 4
case 53: setSkyConfig("material.turbidity", skyboxMaterial.turbidity, 40); break; // 5
case 54: setSkyConfig("material.turbidity", skyboxMaterial.turbidity, 5); break; // 6
case 55: setSkyConfig("material.cameraOffset.y", skyboxMaterial.cameraOffset.y, 50); break; // 7
case 56: setSkyConfig("material.cameraOffset.y", skyboxMaterial.cameraOffset.y, 0); break; // 8
default: break;
}
});
// Set to Day
setSkyConfig("material.inclination", skyboxMaterial.inclination, 0);
// 全屏GUI
const advancedTexture = BABYLON_GUI.AdvancedDynamicTexture.CreateFullscreenUI("myUI");
that.myui = advancedTexture;
// 创建一个高亮层
const highlightLayer = new BABYLON.HighlightLayer('highlightLayer', scene);
// 主控制区
var control_main = new BABYLON_GUI.StackPanel();
control_main.isVertical = false
control_main.top = '-40%';
control_main.left = '-20%';
advancedTexture.addControl(control_main);
// var button_main = BABYLON_GUI.Button.CreateSimpleButton("button_main", "主视角");
// button_main.width = "80px"
// button_main.height = "30px";
// button_main.color = "white";
// button_main.cornerRadius = 20;
// button_main.background = "green";
// control_main.addControl(button_main)
// button_main.onPointerClickObservable.add(() => {
// if (camera.alpha != that.initialAlpha || camera.beta != that.initialBeta || camera.radius != that.initialRadius) {
// var cameraPosition = new BABYLON.Vector3(
// 0 + that.initialRadius * Math.sin(that.initialBeta) * Math.cos(that.initialAlpha),
// 0 + that.initialRadius * Math.cos(that.initialBeta),
// 0 + that.initialRadius * Math.sin(that.initialBeta) * Math.sin(that.initialAlpha)
// );
// var ease = new BABYLON.CubicEase();
// ease.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);
// BABYLON.Animation.CreateAndStartAnimation('at6', camera, 'position', 45, 200, camera.position, cameraPosition, 0, ease);
// BABYLON.Animation.CreateAndStartAnimation('at61', camera, 'target', 45, 200, camera.target, that.initialTarget, 0, ease);
// }
// })
// 高亮显示mesh名
const mesh_rect = new BABYLON_GUI.Rectangle('mesh_rect');
mesh_rect.width = "100px";
mesh_rect.height = "25px";
mesh_rect.background = 'orange';
mesh_rect.alpha = 0.6;
mesh_rect.isVisible = false;
advancedTexture.addControl(mesh_rect);
var mesh_name = new BABYLON_GUI.TextBlock('mesh_name');
mesh_name.text = "";
mesh_name.color = 'white';
mesh_name.fontSize = '14px';
mesh_rect.addControl(mesh_name);
var remoteGlbUrl = process.env.VUE_APP_BASEURL + "/media/model/factory.glb";
BABYLON.SceneLoader.Append(remoteGlbUrl, "", scene, function (scene) {
for (let key in that.sectionNames) {
const value = that.sectionNames[key];
const mesh = scene.getMeshByName(key);
if (mesh) {
const img = new BABYLON_GUI.Image('img', 'img/ignore/qm_enp.png');
img.width = '50px';
img.height = '50px';
img.top = '50%';
img.left = '50%';
img.horizontalAlignment = 10;
img.verticalAlignment = 10;
//建筑标签
const rect1 = new BABYLON_GUI.Rectangle(value + '_rect');
rect1.width = "60px";
rect1.height = "30px";
rect1.cornerRadius = 4;
rect1.color = "Orange";
rect1.thickness = 2;
rect1.background = "green";
rect1.isPointerBlocker = true; // 防止点击穿透
advancedTexture.addControl(img);
var label = new BABYLON_GUI.TextBlock(value + '_label');
label.text = value;
label.color = 'white';
label.fontSize = '14px';
img.linkWithMesh(mesh);
rect1.onPointerDownObservable.add(() => {
const mesh = rect1.linkedMesh;
if (camera.target != mesh.position) {
// console.log('fly to')
// 计算新的相机位置
let position = mesh._parentNode._position
if (mesh._parentNode.id == '__root__') {
position = mesh.position
}
const cameraPosition = new BABYLON.Vector3(
mesh.position.x + 9 * Math.sin(camera.beta) * Math.cos(Math.PI),
mesh.position.y + 9 * Math.cos(camera.beta),
mesh.position.z + 9 * Math.sin(camera.beta) * Math.sin(Math.PI)
);
var ease = new BABYLON.CubicEase();
ease.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT);
BABYLON.Animation.CreateAndStartAnimation('at5', camera, 'position', 45, 200, camera.position, cameraPosition, 0, ease);
BABYLON.Animation.CreateAndStartAnimation('at51', camera, 'target', 45, 200, camera.target, position, 0, ease);
}
let dataViewName = rect1.name.split('_')[0] + '_data_view';
that.activeSectionName = dataViewName;
that.activeSection = 2;
let dataView = advancedTexture.getControlByName(dataViewName);
if (dataView) {
// // 在这里进行矩形的操作
dataView.isVisible = false;
}
});
// 创建一个数据展示层,创建一个StackPanel用于容纳多个文本控件
const data_view = new BABYLON_GUI.StackPanel(value + '_data_view');
data_view.width = '200px'; // StackPanel的宽度
data_view.height = '140px';
data_view.thickness = 1;
data_view.background = 'rgba(0, 34, 51, 0.5)';//暗色
let mgroupName = new BABYLON_GUI.TextBlock(value + '_label');
mgroupName.height = "30px";
mgroupName.width = "120px";
mgroupName.color = "white";
mgroupName.text = value;
mgroupName.shadowColor = '#66b1ff';
mgroupName.shadowBlur = 5;
mgroupName.shadowOffsetX = -2;
mgroupName.shadowOffsetY = 2;
data_view.addControl(mgroupName);
const mgroup = new BABYLON_GUI.Rectangle('mgroup');
mgroup.height = "3px";
mgroup.width = "160px";
mgroup.thickness = 0;
mgroup.background = 'rgba(44, 237, 255, 0.45)';
data_view.addControl(mgroup);
var grid = new BABYLON_GUI.Grid("grid");
grid.width = '200px';
grid.height = '70px';
grid.paddingLeft = 1;
var wd = 2;
var hd = 2;
for (let i = 0; i < wd; i++) {
grid.addRowDefinition(1 / wd);
}
for (let j = 0; j < hd; j++) {
grid.addColumnDefinition(1 / hd);
}
// for (let i = 0; i < wd; i++) {
// for (let j = 0; j < hd; j++) {
// var rc = new BABYLON_GUI.TextBlock("rc" + i + j);
// rc.width = "100%";
// // rc.height = "100%";
// rc.thickness = 0;
// if (j == 0 && i == 0) {
// rc.width = "120px";
// rc.text = "产品产量:";
// rc.color = "white";
// rc.fontSize = '16px';
// } else if (j == 0 && i == 1) {
// rc.width = "120px";
// rc.color = "white";
// rc.fontSize = '16px';
// rc.text = "单位产品电耗:";
// } else if (j == 1 && i == 0) {
// // rc.text = that.mgroupValues[value].total;
// rc.text = "123";
// rc.width = "80px";
// rc.fontSize = '18px';
// rc.color = "rgb(44,237,255)";
// } else if (j == 1 && i == 1) {
// // rc.text = that.mgroupValues[value].total;
// rc.text = "456";
// rc.width = "80px";
// rc.fontSize = '18px';
// rc.color = "rgb(44,237,255)";
// }
// grid.addControl(rc, i, j);
// }
// }
data_view.addControl(grid);
var mgroup_close = BABYLON_GUI.Button.CreateSimpleButton("mgroup_close" + value, '关闭');
mgroup_close.width = "70px"
mgroup_close.height = "25px";
mgroup_close.color = "white";
mgroup_close.cornerRadius = 15;
mgroup_close.fontSize = '12px';
mgroup_close.background = 'rgb(44,237,255,.5)';
mgroup_close.HORIZONTAL_ALIGNMENT_RIGHT = 5;
mgroup_close.onPointerClickObservable.add(() => {
console.log('data_view', data_view)
data_view.isVisible = false;
})
// data_view.addControl(mgroup_close);
// 将StackPanel添加到GUI系统中
// advancedTexture.addControl(data_view);
data_view.linkWithMesh(mesh);
data_view.linkOffsetY = -120;
if (value == '电石渣') {
data_view.linkOffsetY = -290;
}
}
}
engine.hideLoadingUI()
},
function (evt) {
var loadedPercent = 0;
if (evt.lengthComputable) {
loadedPercent = parseInt(evt.loaded * 100 / evt.total);
} else {
var dlCount = evt.loaded / (1024 * 1024);
loadedPercent = Math.floor(dlCount * 100.0) / 100.0;
}
that.loadedPercent = loadedPercent;
})
// 自动旋转checkbox
// var checkbox = new BABYLON_GUI.Checkbox();
// checkbox.width = "20px";
// checkbox.height = "20px";
// checkbox.isChecked = false;
// checkbox.marginLeft = '16px'
// checkbox.color = "green";
// checkbox.onIsCheckedChangedObservable.add(function (value) {
// if (value) {
// camera.useAutoRotationBehavior = true;
// } else {
// camera.useAutoRotationBehavior = false;
// }
// });
// control_main.addControl(checkbox);
// var header = new BABYLON_GUI.TextBlock();
// header.text = "自动旋转";
// header.width = "80px";
// header.textHorizontalAlignment = BABYLON_GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
// header.color = "white";
// control_main.addControl(header);
// 工段数据checkbox
// var checkbox1 = new BABYLON_GUI.Checkbox();
// checkbox1.width = "20px";
// checkbox1.height = "20px";
// checkbox1.isChecked = true;
// checkbox1.marginLeft = '16px'
// checkbox1.color = "green";
// checkbox1.onIsCheckedChangedObservable.add(function (value) {
// if (value) {
// for (let key in that.sectionNames) {
// let name = that.sectionNames[key] + '_data_view';
// console.log(name)
// let dataView = advancedTexture.getControlByName(name);
// dataView.isVisible = true;
// }
// } else {
// for (let key in that.sectionNames) {
// let name = that.sectionNames[key] + '_data_view';
// console.log(name)
// let dataView = advancedTexture.getControlByName(name);
// dataView.isVisible = false;
// }
// }
// });
// control_main.addControl(checkbox1);
// var header1 = new BABYLON_GUI.TextBlock();
// header1.text = "工段数据";
// header1.width = "80px";
// header1.textHorizontalAlignment = BABYLON_GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
// header1.color = "white";
// control_main.addControl(header1);
// 添加抓取事件
canvas.addEventListener('mousemove', (event) => {
// 使用 scene.pick 检测鼠标拾取
const pickResult = scene.pick(scene.pointerX, scene.pointerY);
if (that.currentLightMesh) {
mesh_rect.isVisible = false;
highlightLayer.removeAllMeshes();
}
if (pickResult.hit) {
const mesh = pickResult.pickedMesh;
highlightLayer.removeAllMeshes();
if (/.*[\u4e00-\u9fa5]+.*$/.test(mesh.name) && mesh.name !== '地面1' && mesh.name !== '绿地' && mesh.name !== '停车场') {
// 在选中的 mesh 上添加高亮效果
highlightLayer.addMesh(mesh, new BABYLON.Color3(1, 1, 0.5));
that.currentLightMesh = mesh;
mesh_rect.linkWithMesh(mesh);
let name = mesh.name.split('_')[0];
mesh_name.text = name;
mesh_rect.isVisible = true;
}
}
});
// checkbox.isChecked = true; //默认开启自动旋转
return scene;
};
const scene = createScene();
// scene.debugLayer.show()
engine.runRenderLoop(function () {
scene.render();
});
this.engine = engine;
this.scene = scene;
window.addEventListener("resize", function () {
engine.resize();
});
},
},
unmounted() {
this.close();
},
}
</script>
<style scoped>
.container {
width: 100%;
position: absolute;
height: 100vh;
top: 0vh;
z-index: 0;
padding-top: 8vh;
box-sizing: border-box;
background-image: url('/public/img/enp_blue/bg_enp.png');
background-size: cover;
}
.dashboard {
background-color: black;
font-family: Inter, "-apple-system", BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", "noto sans", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
header {
z-index: 10;
display: flex;
position: relative;
align-items: center;
box-sizing: border-box;
padding: 1.3vh 0.4vw 0 0.4vw;
justify-content: space-between;
}
.headerImg {
width: 100%;
height: 6.7vh;
line-height: 6.3vh;
color: #ffffff;
font-size: 1.8vw;
text-align: center;
position: relative;
}
.sysName {
width: 100%;
text-align: center;
line-height: 6.3vh;
color: #ffffff;
position: absolute;
top: 0;
left: 0;
}
.sysName {
color: #ffffff;
padding-left: 1vw;
font-size: 2vh;
}
.btns_enp {
bottom: 7vh;
left: 28.7vw;
width: 42.6vw;
height: 4.3vh;
position: absolute;
display: flex;
justify-content: space-between;
}
.btns {
width: 8vw;
height: 5vh;
font-size: 2vh;
line-height: 4.9vh;
background-image: url('/public/img/enp_blue/btn.png');
background-size: 100% 100%;
text-align: center;
color: #ffffff;
}
.btns.btnsActive {
background-image: url('/public/img/enp_blue/btn_active.png');
}
.bottom_enp {
left: 0;
bottom: 0;
width: 100%;
height: 5vh;
position: absolute;
background-size: 100% 100%;
background-position: center;
background-image: url('/public/img/enp_blue/bottom_enp.png');
}
.menuWrap {
height: 4.6vh;
margin-right: 1vw;
}
.menuWrap1 {
width: 4.4vw;
background-image: url('/public/img/enp_blue/menu_bg1.png');
background-size: 100% 100%;
}
.menuWrap2 {
width: 7vw;
background-image: url('/public/img/enp_blue/menu_bg2.png');
background-size: 100% 100%;
}
.menuWrapActive.menuWrap1 {
background-image: url('/public/img/enp_blue/menu_bg1_active.png');
}
.menuWrapActive.menuWrap2 {
background-image: url('/public/img/enp_blue/menu_bg2_active.png');
}
.menuItem {
color: #ffffff;
line-height: 4.4vh;
font-size: 1.5vh;
text-align: center;
}
.dropdown {
color: #ffffff;
line-height: 4.5vh;
font-size: 1.4vh;
}
.wraning_icon {
width: 2vh;
height: 2.3vh;
margin-top: 0.9vh;
background-size: cover;
background-image: url('/public/img/enp_blue/warning_enp.png');
}
.user_icon {
width: 2.3vh;
height: 2.3vh;
margin-top: 0.9vh;
margin-left: 2vh;
background-size: cover;
background-image: url('/public/img/enp_blue/user_enp.png');
}
.model {
top: 0;
left: 0;
width: 100%;
background-image: url('/public/img/enp_blue/bg_enp.png');
background-size: cover;
}
#renderCanvas {
width: 100%;
height: 100%
}
#loadingScreen {
position: absolute;
width: 100%;
top: 260px;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
}
.left_other,
.right_other {
position: absolute;
top: 8vh;
width: 20%;
padding: 10px;
}
.right_other {
right: 0
}
.panel {
margin-top: 1.5vh;
background-size: 100% 100%;
}
.panel1,
.panel2 {
background-image: url('/public/img/enp_blue/left_bg1.png');
}
.panel3 {
background-image: url('/public/img/enp_blue/left_bg2.png');
}
.panel4 {
background-image: url('/public/img/enp_blue/right_bg1.png');
}
.panel.panel_big {
background-image: url('/public/img/enp_blue/right_bg2.png');
}
.blockTitle {
width: 100%;
height: 4vh;
position: relative;
}
.blockTitleText {
width: 100%;
height: 4vh;
line-height: 4vh;
position: absolute;
left: 0px;
top: 0px;
z-index: 10;
padding-left: 2.5vw;
color: #ffffff;
font-size: 1vw;
}
.blockTitleImg {
width: 100%;
position: absolute;
left: 0;
top: 0;
}
.eqItem {
display: flex;
/* height: 9vh; */
flex-direction: row;
justify-content: space-between;
flex-wrap: nowrap;
overflow: hidden;
color: #ffffff;
}
.eqImg {
width: 4.8vh;
height: 5.5vh;
flex-shrink: 0;
padding-top: 1.5vh;
}
.eqImg_s {
padding-top: 0;
}
.eqText {
flex: 1;
height: 8vh;
font-size: 1.4vh;
padding-left: 0.5vw;
margin-bottom: 1vh;
background: url('/public/img/enp_blue/eq_border2.svg') no-repeat;
background-size: 100% 100%;
background-size: contain;
}
.eqText_s {
height: 5.5vh;
margin-bottom: 1vh;
background: url('/public/img/enp_blue/eq_border.svg') no-repeat;
background-size: cover;
}
.eqName {
line-height: 4.5vh;
}
.eqText_s>.eqName {
padding-top: 0.5vh;
line-height: 2.5vh;
}
.eqNumWrap {
font-size: 1.2vh;
line-height: 2.5vh;
}
.eqNum {
font-size: 1.8vh;
}
.chart {
width: 100%;
height: 220px;
}
#chart1 {
background-image: url('/public/img/enp_blue/huan_bg.png');
background-size: 75%;
background-repeat: no-repeat;
background-position: center;
}
.pieDataItem {
width: 50%;
height: 35%;
position: relative;
display: inline-block;
margin-top: 10%;
/* border-left: 1px solid #0070FF; */
}
.pieDataText {
height: 2vh;
line-height: 1.9vh;
font-size: 1.1vh;
color: #ffffff;
padding-left: 0.2vw;
}
.pieDataItem:nth-of-type(1) {
.pieDataText {
border-left: 0.3vh solid #0091ff;
}
.pieDataNumber {
border-left: 0.1vh solid #0091ff;
}
}
.pieDataItem:nth-of-type(2) {
.pieDataText {
border-left: 0.3vh solid #0Ed877;
}
.pieDataNumber {
border-left: 0.1vh solid #0Ed877;
}
}
.pieDataItem:nth-of-type(3) {
.pieDataText {
border-left: 0.3vh solid #ffbf60;
}
.pieDataNumber {
border-left: 0.1vh solid #ffbf60;
}
}
.pieDataItem:nth-of-type(4) {
.pieDataText {
border-left: 0.3vh solid #67dbff;
}
.pieDataNumber {
border-left: 0.1vh solid #67dbff;
}
}
.pieDataNumber {
height: 3vh;
line-height: 2.9vh;
font-size: 2vh;
color: #ffffff;
padding-left: 0.2vw;
border-left: 0.1vh solid #0070FF;
}
.beforeLine {
width: 2px;
height: 30%;
position: absolute;
background: #0070FF;
}
.title_s {
height: 3.7vh;
line-height: 3.7vh;
color: #ffffff;
margin-top: 1vh;
font-size: 1.4vh;
text-align: center;
background-image: url('/public/img/enp_blue/little_title.png');
}
.status {
height: 2.6vh;
display: flex;
padding: 0 1vh;
line-height: 2.6vh;
color: #ffffff;
justify-content: space-between;
}
.tableHear {
display: flex;
color: #ffffff;
margin-bottom: 0.5vh;
}
.rowItem {
display: flex;
color: #ffffff;
padding: 0 1vh;
justify-content: space-between;
}
.rowindex {
flex: 1;
height: 4vh;
line-height: 4vh;
text-align: center;
margin-bottom: 1vh;
background-image: url('/public/img/enp_blue/index_bg.png');
background-size: cover;
}
.rowname {
flex: 5;
height: 4vh;
margin: 0 1vh;
padding: 0.5vh;
line-height: 3vh;
box-sizing: border-box;
background: rgba(255, 255, 255, .1);
}
.rownum {
flex: 4;
height: 4vh;
padding: 0.5vh;
line-height: 3vh;
box-sizing: border-box;
background: rgba(255, 255, 255, .1);
}
.right_one {
height: 100%;
display: flex;
color: #ffffff;
position: relative;
justify-content: space-between;
background: url('/public/img/enp_blue/right_one.svg') no-repeat;
background-size: 100% 100%;
}
.leftNumbers {
padding: 2.5vh 1vh;
}
.rightNumbers {
padding: 2.5vh 1vh;
text-align: right;
}
.numberItem {
height: 33.3%;
line-height: 1.6vh;
}
.numberItemName {
font-size: 1.4vh;
line-height: 4vh;
}
.numberItemNum {
font-size: 1.6vh;
}
.numberItemUnit {
font-size: 1.2vh;
}
.ballImg {
position: absolute;
width: 5vw;
height: 5vw;
background-image: url('/public/img/enp_blue/ball.png');
background-size: cover;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.right_one_status {
top: 50%;
left: 50%;
width: 100%;
z-index: 10;
color: #ffffff;
font-size: 2vh;
text-align: center;
position: absolute;
transform: translate(-50%, -50%);
}
/* right2 */
.tableBody {
padding: 0 1vh;
}
.badyItem {
height: 4.6vh;
line-height: 4.6vh;
margin-bottom: 1.4vh;
border-radius: 3px;
color: #ffffff;
font-size: 1.4vh;
display: flex;
border: 1px solid #0091ff;
}
/* right2 */
/* 表格 */
.drawer_container {
background-image: url('/public/img/enp_blue/tableBg.png');
}
/* 表格 */
.left_border {
width: 1vh;
height: 70vh;
position: absolute;
left: 21%;
top: 15vh;
background-size: cover;
background-image: url('/public/img/enp_blue/left_border.png');
}
.right_border {
width: 1vh;
height: 70vh;
position: absolute;
right: 21%;
top: 15vh;
background-size: cover;
background-image: url('/public/img/enp_blue/right_border.png');
}
.pageClass {
width: 100%;
height: 89vh;
position: absolute;
bottom: 0;
left: 0;
}
</style>