From 63b869264fb32b9dd837baa643578caa08aff595 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Mon, 31 Mar 2025 10:28:11 +0800
Subject: [PATCH] feat: 事件点击交互
---
src/views/Home/useUavHome/useUavHome.js | 7
src/assets/images/home/useEventOperate/event.png | 0
src/views/Home/useEventOperate/EventPopUpBox.vue | 112 ++++++++++++++++++
src/views/Home/useEventOperate/useEventOperate.js | 24 ++-
src/assets/images/home/useEventOperate/eventErr.png | 0
src/views/Home/useUavHome/MapPopUpBox.vue | 10 +
src/assets/images/home/useEventOperate/popUpBox.png | 0
src/views/Home/Footer.vue | 170 ++++++++++++++++-----------
8 files changed, 239 insertions(+), 84 deletions(-)
diff --git a/src/assets/images/home/useEventOperate/event.png b/src/assets/images/home/useEventOperate/event.png
new file mode 100644
index 0000000..f2a0f15
--- /dev/null
+++ b/src/assets/images/home/useEventOperate/event.png
Binary files differ
diff --git a/src/assets/images/home/useEventOperate/eventErr.png b/src/assets/images/home/useEventOperate/eventErr.png
new file mode 100644
index 0000000..6e7a026
--- /dev/null
+++ b/src/assets/images/home/useEventOperate/eventErr.png
Binary files differ
diff --git a/src/assets/images/home/useEventOperate/popUpBox.png b/src/assets/images/home/useEventOperate/popUpBox.png
new file mode 100644
index 0000000..ab9ea28
--- /dev/null
+++ b/src/assets/images/home/useEventOperate/popUpBox.png
Binary files differ
diff --git a/src/views/Home/Footer.vue b/src/views/Home/Footer.vue
index 9eefc90..ddbb6f4 100644
--- a/src/views/Home/Footer.vue
+++ b/src/views/Home/Footer.vue
@@ -1,96 +1,128 @@
<template>
<div class="footer">
- <img v-for="item in list" :class="item.className" :src="item.active ? item.activeImg : item.img" alt="" @click="imgClick(item)">
+ <img
+ v-for="item in list"
+ :class="item.className"
+ :src="item.active ? item.activeImg : item.img"
+ alt=""
+ @click="imgClick(item)"
+ />
</div>
<div class="intelligent-introduction-flying">
- <img class="orthophoto" src="@/assets/images/intelligent-introduction-flying.png" alt="">
+ <img class="orthophoto" src="@/assets/images/intelligent-introduction-flying.png" alt="" />
</div>
</template>
<script setup>
-import { useAggregation } from '@/views/Home/useAggregation';
+import img1 from '@/assets/images/home/footer/machine-nest.png';
+import activeImg1 from '@/assets/images/home/footer/machine-nest1.png';
+import img2 from '@/assets/images/home/footer/event.png';
+import activeImg2 from '@/assets/images/home/footer/event1.png';
+import img3 from '@/assets/images/home/footer/panorama.png';
+import activeImg3 from '@/assets/images/home/footer/panorama1.png';
+import img4 from '@/assets/images/home/footer/3D.png';
+import activeImg4 from '@/assets/images/home/footer/3D1.png';
+import img5 from '@/assets/images/home/footer/orthophoto.png';
+import activeImg5 from '@/assets/images/home/footer/orthophoto1.png';
-import img1 from '@/assets/images/home/footer/machine-nest.png'
-import activeImg1 from '@/assets/images/home/footer/machine-nest1.png'
-import img2 from '@/assets/images/home/footer/event.png'
-import activeImg2 from '@/assets/images/home/footer/event1.png'
-import img3 from '@/assets/images/home/footer/panorama.png'
-import activeImg3 from '@/assets/images/home/footer/panorama1.png'
-import img4 from '@/assets/images/home/footer/3D.png'
-import activeImg4 from '@/assets/images/home/footer/3D1.png'
-import img5 from '@/assets/images/home/footer/orthophoto.png'
-import activeImg5 from '@/assets/images/home/footer/orthophoto1.png'
-
-const list = ref([
- {name:'event1',img:img1,activeImg:activeImg1,active:true,className:'machine-nest'},
- {name:'event2',img:img2,activeImg:activeImg2,active:false,className:'event'},
- {name:'event3',img:img3,activeImg:activeImg3,active:false,className:'panorama'},
- {name:'event4',img:img4,activeImg:activeImg4,active:false,className:'threeD'},
- {name:'event5',img:img5,activeImg:activeImg5,active:false,className:'orthophoto'},
-])
+import { useUavHome } from '@/views/Home/useUavHome/useUavHome';
+import { useEventOperate } from '@/views/Home/useEventOperate/useEventOperate';
// 机巢聚合
-const {init,removeAll} = useAggregation()
+const { init, removeAll } = useUavHome();
+// 事件聚合
+const { init: eventInit, removeAll: eventRemove } = useEventOperate();
-const imgClick = (row) => {
- const find = list.value.find(item => item.active)
- if (find.name === row.name) return
- const isFromEvent1 = find.name === 'event1';
- const isToEvent1 = row.name === 'event1';
- if (isFromEvent1 && !isToEvent1) removeAll();
- else if (!isFromEvent1 && isToEvent1) init();
- list.value = list.value.map(item => ({...item,active: item.name === row.name}));
-}
+const list = ref([
+ {
+ name: 'event1',
+ img: img1,
+ activeImg: activeImg1,
+ active: true,
+ className: 'machine-nest',
+ init: init,
+ removeAll: removeAll,
+ },
+ {
+ name: 'event2',
+ img: img2,
+ activeImg: activeImg2,
+ active: false,
+ className: 'event',
+ init: eventInit,
+ removeAll: eventRemove,
+ },
+ { name: 'event3', img: img3, activeImg: activeImg3, active: false, className: 'panorama' },
+ { name: 'event4', img: img4, activeImg: activeImg4, active: false, className: 'threeD' },
+ { name: 'event5', img: img5, activeImg: activeImg5, active: false, className: 'orthophoto' },
+]);
+
+const imgClick = toItem => {
+ const fromItem = list.value.find(item => item.active);
+ if (fromItem.name === toItem.name) return;
+ fromItem?.removeAll?.();
+ nextTick(()=>{
+ toItem?.init?.();
+ })
+ list.value = list.value.map(item => ({ ...item, active: item.name === toItem.name }));
+};
// 销毁前钩子
onBeforeUnmount(() => {
- if (!window.$viewer) return
+ if (!window.$viewer) return;
removeAll();
});
onMounted(() => {
nextTick(() => {
- init()
+ init();
});
});
</script>
<style scoped lang="scss">
- .footer {
- position: absolute;
- bottom: 84px;
- left: 624px;
- img {
- width: 103px;
- height: 119px;
- cursor: pointer;
- }
- .event {
- position: relative;
- left: 40px;
- bottom: 15px;
- }
- .panorama {
- position: relative;
- left: 80px;
- bottom: 34px;
- }
- .threeD {
- position: relative;
- left: 120px;
- bottom: 15px;
- }
- .orthophoto {
- position: relative;
- left: 160px;
- }
+.footer {
+ position: absolute;
+ bottom: 84px;
+ left: 624px;
+
+ img {
+ width: 103px;
+ height: 119px;
+ cursor: pointer;
}
- .intelligent-introduction-flying {
- position: absolute;
- left: 888px;
- bottom: 23px;
- img {
- width: 146px;
- height: 54px;
- }
+
+ .event {
+ position: relative;
+ left: 40px;
+ bottom: 15px;
}
+
+ .panorama {
+ position: relative;
+ left: 80px;
+ bottom: 34px;
+ }
+
+ .threeD {
+ position: relative;
+ left: 120px;
+ bottom: 15px;
+ }
+
+ .orthophoto {
+ position: relative;
+ left: 160px;
+ }
+}
+
+.intelligent-introduction-flying {
+ position: absolute;
+ left: 888px;
+ bottom: 23px;
+
+ img {
+ width: 146px;
+ height: 54px;
+ }
+}
</style>
diff --git a/src/views/Home/useEventOperate/EventPopUpBox.vue b/src/views/Home/useEventOperate/EventPopUpBox.vue
new file mode 100644
index 0000000..ed506c3
--- /dev/null
+++ b/src/views/Home/useEventOperate/EventPopUpBox.vue
@@ -0,0 +1,112 @@
+<script setup>
+import { Close } from '@element-plus/icons-vue';
+
+const list = [
+ { name: '执行中', value: '1', color: '#FFA768' },
+ { name: '在线', value: '20', color: '#8EFFAC' },
+ { name: '离线', value: '14', color: '#FFFFFF' },
+ { name: '异常', value: '25', color: '#FF6262' },
+];
+
+const props = defineProps(['data', 'removeLabel']);
+</script>
+
+<template>
+ <div class="mapPopUpBox">
+ <div class="title">
+ 违章建筑
+ <el-icon class="header-close" @click="props.removeLabel">
+ <Close />
+ </el-icon>
+ </div>
+ <div class="content">
+ <img
+ class="eventImage"
+ src="@/assets/images/home/useEventOperate/eventErr.png"
+ alt="Event Image"
+ />
+ <div class="details">
+ <div class="label">位置:</div>
+ <div class="value point">112.12345 23.98726</div>
+ <div class="label">时间:</div>
+ <div class="value">2025.08.16 22:25</div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style scoped lang="scss">
+.mapPopUpBox {
+ width: 271px;
+ height: 173px;
+ background: url('@/assets/images/home/useEventOperate/popUpBox.png') no-repeat center / 100% 100%;
+ padding: 13px 15px;
+ pointer-events: all;
+
+ .title {
+ font-family: YouSheBiaoTiHei, YouSheBiaoTiHei, serif;
+ font-weight: 400;
+ font-size: 18px;
+ line-height: 16px;
+ background: linear-gradient(180deg, #A8E5FB 0%, #E6F8FF 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ -moz-background-clip: text;
+ -moz-text-fill-color: transparent;
+ background-clip: text;
+ text-fill-color: transparent;
+ margin-bottom: 10px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+
+ .header-close {
+ width: 20px;
+ height: 100%;
+ line-height: 100%;
+ display: flex;
+ align-items: center;
+ color: #9cd5ff;
+ pointer-events: all;
+ cursor: pointer;
+ }
+ }
+
+ .content {
+ height: 102px;
+ width: 240px;
+ display: flex;
+ align-items: center;
+
+ img {
+ height: 102px;
+ width: 102px;
+ margin-right: 10px;
+ }
+
+ .details {
+ .label {
+ font-family: Source Han Sans CN, Source Han Sans CN;
+ font-weight: 400;
+ font-size: 14px;
+ color: #7babd7;
+ line-height: 16px;
+ margin-bottom: 2px;
+ }
+
+ .value {
+ font-family: Source Han Sans CN, Source Han Sans CN;
+ font-weight: 400;
+ font-size: 14px;
+ color: #d8edff;
+ line-height: 16px;
+ margin-bottom: 2px;
+ }
+
+ .point {
+ margin-bottom: 14px;
+ }
+ }
+ }
+}
+</style>
diff --git a/src/views/Home/useAggregation.js b/src/views/Home/useEventOperate/useEventOperate.js
similarity index 89%
copy from src/views/Home/useAggregation.js
copy to src/views/Home/useEventOperate/useEventOperate.js
index b724256..56033b9 100644
--- a/src/views/Home/useAggregation.js
+++ b/src/views/Home/useEventOperate/useEventOperate.js
@@ -1,16 +1,18 @@
import * as Cesium from 'cesium';
import data2 from '@/assets/images/home/homeRight/data2.png';
import data1 from '@/assets/images/home/homeRight/data1.png';
+import eventImg from '@/assets/images/home/useEventOperate/event.png';
import jiangxishi from '@/assets/geojson/jiangxishi.json';
import jiangxi from '@/assets/geojson/jiangxi.json';
import zg from '@/assets/geojson/zg.json';
-import MapPopUpBox from '@/views/Home/MapPopUpBox.vue';
+import EventPopUpBox from './EventPopUpBox.vue';
import { render } from 'vue';
+import store from '@/store';
/**
- * 机巢聚合功能
+ * 事件聚合功能
*/
-export const useAggregation = () => {
+export const useEventOperate = () => {
const scalingJudgment = [
{ name: '县', value: [0, 48651], gJson: null },
{ name: '市', value: [48651, 314863], gJson: jiangxishi },
@@ -54,7 +56,7 @@
),
label: {
// 随机整数
- text: Math.floor(Math.random() * 100) + '号机巢',
+ text: Math.floor(Math.random() * 100) + '号事件',
font: '14pt monospace',
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
@@ -64,7 +66,7 @@
pixelOffset: new Cesium.Cartesian2(0, -9),
},
billboard: {
- image: new Cesium.ConstantProperty(data1),
+ image: new Cesium.ConstantProperty(eventImg),
width: 24,
height: 24,
},
@@ -87,7 +89,7 @@
position: position,
label: {
// 随机整数
- text: feature.name + Math.floor(Math.random() * 100),
+ text: Math.floor(Math.random() * 100) + '个事件',
font: '14pt monospace',
fillColor: Cesium.Color.WHITE,
outlineColor: Cesium.Color.BLACK,
@@ -127,11 +129,11 @@
// 获取弹框box
const getLabelDom = () => {
- const vNode = h(MapPopUpBox, { data: '参数', removeLabel });
+ const vNode = h(EventPopUpBox, { data: '参数', removeLabel });
const tooltipContainer = document.createElement('div');
tooltipContainer.id = 'mapPopUpBox';
tooltipContainer.style.position = 'absolute';
- tooltipContainer.style.transform = 'translateY(-50%)';
+ tooltipContainer.style.transform = 'translate(-50%,-110%)';
tooltipContainer.style.pointerEvents = 'none';
document.querySelector('.page-index').append(tooltipContainer);
render(vNode, tooltipContainer);
@@ -140,6 +142,9 @@
// 弹框位置刷新
const labelBox = () => {
+ store.commit('setSingleUavHome', {
+ id: '123'
+ });
let dom = document.querySelector('#mapPopUpBox');
if (!dom) {
dom = getLabelDom();
@@ -157,7 +162,8 @@
const pickedObject = viewer.scene.pick(click.position);
if (Cesium.defined(pickedObject) && pickedObject.id) {
const entity = pickedObject.id;
- positionC3 = entity.position._value;
+ positionC3 = entity?.position?._value;
+ if (!positionC3) return;
viewer.scene.postRender.removeEventListener(labelBox);
viewer.scene.postRender.addEventListener(labelBox);
}
diff --git a/src/views/Home/MapPopUpBox.vue b/src/views/Home/useUavHome/MapPopUpBox.vue
similarity index 90%
rename from src/views/Home/MapPopUpBox.vue
rename to src/views/Home/useUavHome/MapPopUpBox.vue
index cc4d0e9..c49c4df 100644
--- a/src/views/Home/MapPopUpBox.vue
+++ b/src/views/Home/useUavHome/MapPopUpBox.vue
@@ -15,7 +15,7 @@
<div class="mapPopUpBox">
<div class="header">
<div class="headerLeft">
- <img class="header-image" src="@/assets/images/home/MapPopUpBox/titleImg.png" alt="" />
+ <img class="header-image" src="../../../assets/images/home/mapPopUpBox/titleImg.png" alt="" />
<div class="header-title">安义县机场</div>
</div>
<el-icon class="header-close" @click="props.removeLabel">
@@ -46,7 +46,7 @@
.mapPopUpBox {
width: 418px;
height: 240px;
- background: url('@/assets/images/home/MapPopUpBox/mapPopUpBg.png') no-repeat center / 100% 100%;
+ background: url('@/assets/images/home/mapPopUpBox/mapPopUpBg.png') no-repeat center / 100% 100%;
padding-left: 98px;
.header {
@@ -76,6 +76,10 @@
background: linear-gradient(180deg, #ffffff 41%, #35d0ff 86%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
+ -moz-background-clip: text;
+ -moz-text-fill-color: transparent;
+ background-clip: text;
+ text-fill-color: transparent;
margin-left: 4px;
}
@@ -137,7 +141,7 @@
.status-item {
width: 66px;
height: 54px;
- background: url('@/assets/images/home/MapPopUpBox/itembg.png') no-repeat center / 100% 100%;
+ background: url('@/assets/images/home/mapPopUpBox/itembg.png') no-repeat center / 100% 100%;
text-align: center;
.status-value {
diff --git a/src/views/Home/useAggregation.js b/src/views/Home/useUavHome/useUavHome.js
similarity index 96%
rename from src/views/Home/useAggregation.js
rename to src/views/Home/useUavHome/useUavHome.js
index b724256..4e08252 100644
--- a/src/views/Home/useAggregation.js
+++ b/src/views/Home/useUavHome/useUavHome.js
@@ -4,13 +4,13 @@
import jiangxishi from '@/assets/geojson/jiangxishi.json';
import jiangxi from '@/assets/geojson/jiangxi.json';
import zg from '@/assets/geojson/zg.json';
-import MapPopUpBox from '@/views/Home/MapPopUpBox.vue';
+import MapPopUpBox from '@/views/Home/useUavHome/MapPopUpBox.vue';
import { render } from 'vue';
/**
* 机巢聚合功能
*/
-export const useAggregation = () => {
+export const useUavHome = () => {
const scalingJudgment = [
{ name: '县', value: [0, 48651], gJson: null },
{ name: '市', value: [48651, 314863], gJson: jiangxishi },
@@ -157,7 +157,8 @@
const pickedObject = viewer.scene.pick(click.position);
if (Cesium.defined(pickedObject) && pickedObject.id) {
const entity = pickedObject.id;
- positionC3 = entity.position._value;
+ positionC3 = entity?.position?._value;
+ if (!positionC3) return;
viewer.scene.postRender.removeEventListener(labelBox);
viewer.scene.postRender.addEventListener(labelBox);
}
--
Gitblit v1.9.3