Procházet zdrojové kódy

综合业务页面顶部添加统计卡片,底部添加防汛抗旱、水环境、水资源的切换

WQQ před 2 týdny
rodič
revize
ec62fd92e6

+ 1 - 1
src/views/map/index.vue

@@ -486,7 +486,7 @@ function handleMenuSelect(index) {
     } else if (index === "2") {
       gsap.to(".water-resource-content .module-card", { x: 0, opacity: 1, duration: 0.5, stagger: 0.1 })
     } else if (index === "3") {
-      gsap.to(".water-station-content .water-station-card", { x: 0, opacity: 1, duration: 0.5, stagger: 0.1 })
+      // 综合业务页面的动画效果由其自身处理
     } else if (index === "4") {
       gsap.to(".history-content .event-card", { x: 0, opacity: 1, duration: 0.5 })
       gsap.to(".history-content .timeline-container", { y: 0, opacity: 1, duration: 0.5, delay: 0.2 })

+ 5 - 3
src/views/waterStation/TopStats.vue

@@ -56,12 +56,12 @@ const statsData = ref([
 <style lang="scss">
 .top-count-card {
   position: absolute;
-  left: 560px;
-  right: 560px;
+  left: 0;
+  right: 0;
   top: 130px;
   display: flex;
   justify-content: center;
-  z-index: 9;
+  z-index: 10;
   & > div {
     padding: 0 35px;
   }
@@ -71,6 +71,8 @@ const statsData = ref([
   display: flex;
   align-items: center;
   padding: 10px;
+  transform: translateY(150%);
+  opacity: 0;
   &-icon {
     width: 48px;
     height: 48px;

+ 162 - 1
src/views/waterStation/index.vue

@@ -270,15 +270,46 @@
         </div>
       </div>
     </template>
+    
+    <!-- 底部托盘 -->
+    <div class="bottom-tray">
+      <!-- svg线条动画 -->
+      <mSvglineAnimation class="bottom-svg-line-left" :width="721" :height="57" color="#00BFFF" :strokeWidth="2"
+        :dir="[0, 1]" :length="50"
+        path="M1 56.6105C1 31.5123 185.586 10.0503 451.904 1.35519C458.942 1.12543 465.781 4.00883 470.505 9.22964L484.991 25.2383C487.971 28.4775 492.938 30.4201 498.254 30.4201H720.142">
+      </mSvglineAnimation>
+      <mSvglineAnimation class="bottom-svg-line-left bottom-svg-line-right" :width="721" :height="57" color="#00BFFF"
+        :strokeWidth="2" :dir="[0, 1]" :length="50"
+        path="M1 56.6105C1 31.5123 185.586 10.0503 451.904 1.35519C458.942 1.12543 465.781 4.00883 470.505 9.22964L484.991 25.2383C487.971 28.4775 492.938 30.4201 498.254 30.4201H720.142">
+      </mSvglineAnimation>
+      <!-- 做箭头 -->
+      <div class="bottom-tray-arrow">
+        <img src="@/assets/images/bottom-menu-arrow-big.svg" alt="" />
+        <img src="@/assets/images/bottom-menu-arrow-small.svg" alt="" />
+      </div>
+      <!-- 底部菜单 -->
+      <div class="bottom-menu">
+        <div class="bottom-menu-item is-active"><span>防汛抗旱</span></div>
+        <div class="bottom-menu-item"><span>水环境</span></div>
+        <div class="bottom-menu-item"><span>水资源</span></div>
+      </div>
+      <!-- 右箭头 -->
+      <div class="bottom-tray-arrow is-reverse">
+        <img src="@/assets/images/bottom-menu-arrow-big.svg" alt="" />
+        <img src="@/assets/images/bottom-menu-arrow-small.svg" alt="" />
+      </div>
+    </div>
   </div>
 </template>
 
 <script setup>
-import { ref, computed } from "vue"
+import { ref, computed, onMounted, nextTick } from "vue"
 import mCard from "@/components/mCard/index.vue"
 import VChart from "vue-echarts"
 import * as echarts from "echarts"
 import TopStats from "./TopStats.vue"
+import mSvglineAnimation from "@/components/mSvglineAnimation/index.vue"
+import gsap from "gsap"
 
 defineProps({
   selectedPolderDetail: {
@@ -748,6 +779,15 @@ const rainfallChartOption = ref({
     }
   ]
 })
+
+// 组件挂载时执行动画
+onMounted(() => {
+  nextTick(() => {
+    gsap.to(".water-station-content .water-station-card", { x: 0, opacity: 1, duration: 0.5, stagger: 0.1 })
+    gsap.to(".water-station-content .count-card", { y: 0, opacity: 1, duration: 0.5, stagger: 0.1 })
+    gsap.to(".water-station-content .bottom-tray", { y: 0, opacity: 1, duration: 0.5 })
+  })
+})
 </script>
 
 <style lang="scss">
@@ -760,6 +800,127 @@ const rainfallChartOption = ref({
   z-index: 100;
 }
 
+.bottom-tray {
+  position: absolute;
+  left: 50%;
+  bottom: 0;
+  z-index: 3;
+  margin-left: -960px;
+  width: 1920px;
+  height: 90px;
+  box-sizing: border-box;
+  padding-top: 20px;
+  display: flex;
+  justify-content: center;
+  background: url("~@/assets/images/bottom-menu-bg.png") no-repeat;
+  background-size: contain;
+  
+  &-arrow {
+    display: flex;
+    align-items: center;
+    height: 30px;
+    
+    &.is-reverse {
+      transform: scaleX(-1);
+    }
+    
+    img {
+      animation: arrowAnimate 2s ease-in-out infinite;
+    }
+    
+    img:last-child {
+      animation: arrowAnimate2 2s ease-in-out infinite;
+    }
+  }
+  
+  .bottom-menu {
+    display: flex;
+    padding: 0 20px;
+    
+    &-item {
+      width: 100px;
+      height: 32px;
+      background: url("~@/assets/images/bottom-menu-btn.png") no-repeat;
+      background-size: 100%;
+      font-size: 15px;
+      letter-spacing: 1.6px;
+      text-align: center;
+      line-height: 30px;
+      cursor: pointer;
+      pointer-events: all;
+      
+      span {
+        display: block;
+        width: 100px;
+        height: 32px;
+        font-weight: 700;
+        background: -webkit-linear-gradient(rgba(117, 232, 255, 1), rgba(255, 255, 255, 1));
+        -webkit-background-clip: text;
+        -webkit-text-fill-color: transparent;
+      }
+      
+      &:hover,
+      &.is-active {
+        background: url("~@/assets/images/bottom-menu-btn-hover.png") no-repeat;
+        background-size: 100%;
+      }
+    }
+  }
+}
+
+.bottom-svg-line-left,
+.bottom-svg-line-right {
+  position: absolute;
+  right: 50%;
+  width: 721px;
+  height: 57px;
+  margin-right: -5px;
+  bottom: -21px;
+}
+
+.bottom-svg-line-right {
+  transform: scaleX(-1);
+  left: 50%;
+  right: inherit;
+  margin-right: inherit;
+  margin-left: -5px;
+}
+
+@keyframes arrowAnimate {
+  0% {
+    transform: translateX(0);
+  }
+  50% {
+    transform: translateX(10px);
+  }
+  100% {
+    transform: translateX(0);
+  }
+}
+
+@keyframes arrowAnimate2 {
+  0% {
+    transform: translateX(0);
+  }
+  50% {
+    transform: translateX(5px);
+  }
+  100% {
+    transform: translateX(0);
+  }
+}
+
+/* 初始化动画开始位置 */
+.count-card {
+  transform: translateY(150%);
+  opacity: 0;
+}
+
+.bottom-tray {
+  transform: translateY(100%);
+  opacity: 0;
+}
+
 .left-panel {
   position: absolute;
   z-index: 4;