|
@@ -180,7 +180,12 @@
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Bottom Dock (overlay on map) -->
|
|
<!-- Bottom Dock (overlay on map) -->
|
|
|
- <div class="dock-wrap" @mousemove="onDockMove" @mouseleave="onDockLeave">
|
|
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="dock-wrap"
|
|
|
|
|
+ :class="{ 'is-hidden': !isNavVisible }"
|
|
|
|
|
+ @mousemove="onDockMove"
|
|
|
|
|
+ @mouseleave="onDockLeave"
|
|
|
|
|
+ >
|
|
|
<div class="dock-arrow left" @click="dockPrev" title="上一页"></div>
|
|
<div class="dock-arrow left" @click="dockPrev" title="上一页"></div>
|
|
|
<div class="dockbar">
|
|
<div class="dockbar">
|
|
|
<div
|
|
<div
|
|
@@ -201,6 +206,8 @@
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="bottom-sensor" @mouseenter="isNavVisible = true"></div>
|
|
|
</section>
|
|
</section>
|
|
|
|
|
|
|
|
<!-- Right -->
|
|
<!-- Right -->
|
|
@@ -312,6 +319,8 @@ export default {
|
|
|
name: "Home",
|
|
name: "Home",
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
|
|
+ isNavVisible: true,
|
|
|
|
|
+ timer: null,
|
|
|
currentHoverIndex: null,
|
|
currentHoverIndex: null,
|
|
|
baseW: 1920,
|
|
baseW: 1920,
|
|
|
baseH: 1080,
|
|
baseH: 1080,
|
|
@@ -478,6 +487,13 @@ onlineChart: null,
|
|
|
this.onlineChart && this.onlineChart.dispose();
|
|
this.onlineChart && this.onlineChart.dispose();
|
|
|
this.controlChart && this.controlChart.dispose();
|
|
this.controlChart && this.controlChart.dispose();
|
|
|
this.deviceChart && this.deviceChart.dispose();
|
|
this.deviceChart && this.deviceChart.dispose();
|
|
|
|
|
+ // 组件销毁前清除定时器,防止内存泄漏
|
|
|
|
|
+ if (this.timer) clearTimeout(this.timer);
|
|
|
|
|
+ },
|
|
|
|
|
+ mounted () {
|
|
|
|
|
+ this.timer = setTimeout(() => {
|
|
|
|
|
+ this.isNavVisible = false;
|
|
|
|
|
+ }, 2000); // 2000毫秒(2秒)后收起底部菜单
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
onMouseMove(e) {
|
|
onMouseMove(e) {
|
|
@@ -499,10 +515,22 @@ onlineChart: null,
|
|
|
const rect = this.$el.getBoundingClientRect();
|
|
const rect = this.$el.getBoundingClientRect();
|
|
|
this.mouseX = e.clientX - rect.left;
|
|
this.mouseX = e.clientX - rect.left;
|
|
|
this.mouseY = e.clientY - rect.top;
|
|
this.mouseY = e.clientY - rect.top;
|
|
|
|
|
+
|
|
|
|
|
+ // 显示菜单
|
|
|
|
|
+ if (this.timer) {
|
|
|
|
|
+ clearTimeout(this.timer);
|
|
|
|
|
+ this.timer = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.isNavVisible = true;
|
|
|
},
|
|
},
|
|
|
onDockLeave() {
|
|
onDockLeave() {
|
|
|
this.mouseX = null;
|
|
this.mouseX = null;
|
|
|
this.mouseY = null;
|
|
this.mouseY = null;
|
|
|
|
|
+
|
|
|
|
|
+ // 收起菜单
|
|
|
|
|
+ this.timer = setTimeout(() => {
|
|
|
|
|
+ this.isNavVisible = false;
|
|
|
|
|
+ }, 2000); // 2000毫秒(2秒)后收起
|
|
|
},
|
|
},
|
|
|
navItemStyle(idx) {
|
|
navItemStyle(idx) {
|
|
|
if (this.mouseX == null) return { transform: "translateZ(0) scale(1)" };
|
|
if (this.mouseX == null) return { transform: "translateZ(0) scale(1)" };
|
|
@@ -1399,6 +1427,22 @@ onlineChart: null,
|
|
|
justify-content:center;
|
|
justify-content:center;
|
|
|
gap: calc(var(--s) * 22px);
|
|
gap: calc(var(--s) * 22px);
|
|
|
}
|
|
}
|
|
|
|
|
+.dock-wrap.is-hidden {
|
|
|
|
|
+ opacity: 0.3; /* 变透明一点,更有科技感 */
|
|
|
|
|
+ filter: blur(2px); /* 甚至可以加一点模糊 */
|
|
|
|
|
+ transition: transform .8s cubic-bezier(0.45, 0, 0.55, 1); /* 经典的平滑缓冲 */
|
|
|
|
|
+ transform: translateX(-50%) translateY(90%);
|
|
|
|
|
+}
|
|
|
|
|
+/* 底部感应区 */
|
|
|
|
|
+.bottom-sensor {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 10px; /* 只需要很窄一条 */
|
|
|
|
|
+ z-index: 998;
|
|
|
|
|
+ background: transparent;
|
|
|
|
|
+}
|
|
|
.dock-arrow{
|
|
.dock-arrow{
|
|
|
width: calc(var(--s) * 54px);
|
|
width: calc(var(--s) * 54px);
|
|
|
height: calc(var(--s) * 54px);
|
|
height: calc(var(--s) * 54px);
|