|
@@ -1,178 +1,37 @@
|
|
|
<template>
|
|
<template>
|
|
|
- <div class="water-resource-page">
|
|
|
|
|
- <mapScene ref="mapSceneRef"></mapScene>
|
|
|
|
|
- <div class="water-resource-wrap" id="water-resource">
|
|
|
|
|
- <m-header title="昆山水务水文系统" sub-text="Hydrological Visualization System">
|
|
|
|
|
- <template v-slot:left>
|
|
|
|
|
- <div class="m-header-weather"><span>小雪</span><span>-4℃</span></div>
|
|
|
|
|
- </template>
|
|
|
|
|
- <template v-slot:right>
|
|
|
|
|
- <div class="m-header-date"><span>2025-12-11</span><span>17:53:16</span></div>
|
|
|
|
|
- </template>
|
|
|
|
|
- </m-header>
|
|
|
|
|
- <div class="top-menu">
|
|
|
|
|
- <mMenu :default-active="state.activeIndex" @select="handleMenuSelect">
|
|
|
|
|
- <mMenuItem index="1">区域总览</mMenuItem>
|
|
|
|
|
- <mMenuItem index="2">水质监测</mMenuItem>
|
|
|
|
|
- <mMenuItem index="3">水文数据</mMenuItem>
|
|
|
|
|
- <div class="top-menu-mid-space"></div>
|
|
|
|
|
- <mMenuItem index="4">防洪预警</mMenuItem>
|
|
|
|
|
- <mMenuItem index="5">融合体系</mMenuItem>
|
|
|
|
|
- <mMenuItem index="6">系统设置</mMenuItem>
|
|
|
|
|
- </mMenu>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="left-column">
|
|
|
|
|
- <div class="left-column-3d">
|
|
|
|
|
- <div class="module-card">
|
|
|
|
|
- <SystemIntegration />
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="module-card">
|
|
|
|
|
- <IntegrationEffect />
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <div class="water-resource-content">
|
|
|
|
|
+ <div class="left-column">
|
|
|
|
|
+ <div class="left-column-3d">
|
|
|
|
|
+ <div class="module-card">
|
|
|
|
|
+ <SystemIntegration />
|
|
|
</div>
|
|
</div>
|
|
|
- </div>
|
|
|
|
|
- <div class="right-column">
|
|
|
|
|
- <div class="right-column-3d">
|
|
|
|
|
- <div class="module-card">
|
|
|
|
|
- <CollaborativeProcess />
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="module-card">
|
|
|
|
|
- <DemonstrationBase />
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <div class="module-card">
|
|
|
|
|
+ <IntegrationEffect />
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="water-resource-left-zsline"></div>
|
|
|
|
|
- <div class="water-resource-right-zsline"></div>
|
|
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="loading">
|
|
|
|
|
- <div class="loading-text">
|
|
|
|
|
- <span style="--index: 1">L</span>
|
|
|
|
|
- <span style="--index: 2">O</span>
|
|
|
|
|
- <span style="--index: 3">A</span>
|
|
|
|
|
- <span style="--index: 4">D</span>
|
|
|
|
|
- <span style="--index: 5">I</span>
|
|
|
|
|
- <span style="--index: 6">N</span>
|
|
|
|
|
- <span style="--index: 7">G</span>
|
|
|
|
|
- </div>
|
|
|
|
|
- <div class="loading-progress">
|
|
|
|
|
- <span class="value">{{ state.progress }}</span>
|
|
|
|
|
- <span class="unit">%</span>
|
|
|
|
|
|
|
+ <div class="right-column">
|
|
|
|
|
+ <div class="right-column-3d">
|
|
|
|
|
+ <div class="module-card">
|
|
|
|
|
+ <CollaborativeProcess />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="module-card">
|
|
|
|
|
+ <DemonstrationBase />
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
|
-import { shallowRef, ref, reactive, onMounted, onBeforeUnmount } from "vue"
|
|
|
|
|
-import { useRouter } from "vue-router"
|
|
|
|
|
-import mapScene from "@/views/map/map.vue"
|
|
|
|
|
-import mHeader from "@/components/mHeader/index.vue"
|
|
|
|
|
-import mMenu from "@/components/mMenu/index.vue"
|
|
|
|
|
-import mMenuItem from "@/components/mMenuItem/index.vue"
|
|
|
|
|
import SystemIntegration from "./components/SystemIntegration.vue"
|
|
import SystemIntegration from "./components/SystemIntegration.vue"
|
|
|
import CollaborativeProcess from "./components/CollaborativeProcess.vue"
|
|
import CollaborativeProcess from "./components/CollaborativeProcess.vue"
|
|
|
import IntegrationEffect from "./components/IntegrationEffect.vue"
|
|
import IntegrationEffect from "./components/IntegrationEffect.vue"
|
|
|
import DemonstrationBase from "./components/DemonstrationBase.vue"
|
|
import DemonstrationBase from "./components/DemonstrationBase.vue"
|
|
|
-import { Assets } from "@/views/map/assets.js"
|
|
|
|
|
-import emitter from "@/utils/emitter"
|
|
|
|
|
-import gsap from "gsap"
|
|
|
|
|
-import autofit from "autofit.js"
|
|
|
|
|
-
|
|
|
|
|
-const router = useRouter()
|
|
|
|
|
-const assets = shallowRef(null)
|
|
|
|
|
-const assetsInstance = shallowRef(null)
|
|
|
|
|
-const mapSceneRef = ref(null)
|
|
|
|
|
-const state = reactive({
|
|
|
|
|
- progress: 0,
|
|
|
|
|
- activeIndex: "5",
|
|
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-onMounted(() => {
|
|
|
|
|
- emitter.$on("mapPlayComplete", handleMapPlayComplete)
|
|
|
|
|
- assets.value = autofit.init({
|
|
|
|
|
- dh: 1080,
|
|
|
|
|
- dw: 1920,
|
|
|
|
|
- el: "#water-resource",
|
|
|
|
|
- resize: true,
|
|
|
|
|
- })
|
|
|
|
|
- initAssets(async () => {
|
|
|
|
|
- emitter.$emit("loadMap", assetsInstance.value)
|
|
|
|
|
- await hideLoading()
|
|
|
|
|
- mapSceneRef.value.play()
|
|
|
|
|
- })
|
|
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-onBeforeUnmount(() => {
|
|
|
|
|
- emitter.$off("mapPlayComplete", handleMapPlayComplete)
|
|
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-function initAssets(onLoadCallback) {
|
|
|
|
|
- assetsInstance.value = new Assets()
|
|
|
|
|
- let params = { progress: 0 }
|
|
|
|
|
- assetsInstance.value.instance.on("onProgress", (path, itemsLoaded, itemsTotal) => {
|
|
|
|
|
- let p = Math.floor((itemsLoaded / itemsTotal) * 100)
|
|
|
|
|
- gsap.to(params, {
|
|
|
|
|
- progress: p,
|
|
|
|
|
- onUpdate: () => {
|
|
|
|
|
- state.progress = Math.floor(params.progress)
|
|
|
|
|
- },
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
- assetsInstance.value.instance.on("onLoad", () => {
|
|
|
|
|
- onLoadCallback && onLoadCallback()
|
|
|
|
|
- })
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-async function hideLoading() {
|
|
|
|
|
- return new Promise((resolve) => {
|
|
|
|
|
- let tl = gsap.timeline()
|
|
|
|
|
- tl.to(".loading-text span", {
|
|
|
|
|
- y: "200%",
|
|
|
|
|
- opacity: 0,
|
|
|
|
|
- ease: "power4.inOut",
|
|
|
|
|
- duration: 2,
|
|
|
|
|
- stagger: 0.2,
|
|
|
|
|
- })
|
|
|
|
|
- tl.to(".loading-progress", { opacity: 0, ease: "power4.inOut", duration: 2 }, "<")
|
|
|
|
|
- tl.to(".loading", {
|
|
|
|
|
- opacity: 0,
|
|
|
|
|
- ease: "power4.inOut",
|
|
|
|
|
- onComplete: () => resolve(),
|
|
|
|
|
- }, "-=1")
|
|
|
|
|
- })
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-function handleMenuSelect(index) {
|
|
|
|
|
- state.activeIndex = index
|
|
|
|
|
- if (index === "1") {
|
|
|
|
|
- router.push("/map")
|
|
|
|
|
- } else if (index === "5") {
|
|
|
|
|
- router.push("/waterResource")
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-function handleMapPlayComplete() {
|
|
|
|
|
- let tl = gsap.timeline({ paused: false })
|
|
|
|
|
- let leftCards = gsap.utils.toArray(".left-column .module-card")
|
|
|
|
|
- let rightCards = gsap.utils.toArray(".right-column .module-card")
|
|
|
|
|
- tl.addLabel("start", 0.5)
|
|
|
|
|
- tl.to(".m-header", { y: 0, opacity: 1, duration: 1.5, ease: "power4.out" }, "start")
|
|
|
|
|
- tl.to(".top-menu", { y: 0, opacity: 1, duration: 1.5, ease: "power4.out" }, "-=1")
|
|
|
|
|
- tl.to(leftCards, { x: 0, opacity: 1, stagger: 0.2, duration: 1.5, ease: "power4.out" }, "-=1")
|
|
|
|
|
- tl.to(rightCards, { x: 0, opacity: 1, stagger: 0.2, duration: 1.5, ease: "power4.out" }, "-=1.3")
|
|
|
|
|
-}
|
|
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss">
|
|
<style lang="scss">
|
|
|
-@use "~@/assets/style/home.scss";
|
|
|
|
|
-
|
|
|
|
|
-.water-resource-page {
|
|
|
|
|
- position: relative;
|
|
|
|
|
- width: 100%;
|
|
|
|
|
- height: 100%;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.water-resource-wrap {
|
|
|
|
|
|
|
+.water-resource-content {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
top: 0;
|
|
top: 0;
|
|
|
left: 0;
|
|
left: 0;
|
|
@@ -182,36 +41,12 @@ function handleMapPlayComplete() {
|
|
|
pointer-events: none;
|
|
pointer-events: none;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-.m-header-weather,
|
|
|
|
|
-.m-header-date {
|
|
|
|
|
- span {
|
|
|
|
|
- padding-right: 10px;
|
|
|
|
|
- color: #c4f3fe;
|
|
|
|
|
- font-size: 14px;
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.top-menu {
|
|
|
|
|
- position: absolute;
|
|
|
|
|
- left: 0;
|
|
|
|
|
- right: 0;
|
|
|
|
|
- top: 40px;
|
|
|
|
|
- z-index: 3;
|
|
|
|
|
- display: flex;
|
|
|
|
|
- justify-content: center;
|
|
|
|
|
- transform: translateY(-250%);
|
|
|
|
|
- opacity: 0;
|
|
|
|
|
- .top-menu-mid-space {
|
|
|
|
|
- width: 800px;
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
.left-column {
|
|
.left-column {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
|
z-index: 4;
|
|
z-index: 4;
|
|
|
width: 398px;
|
|
width: 398px;
|
|
|
left: 32px;
|
|
left: 32px;
|
|
|
- top: 126px;
|
|
|
|
|
|
|
+ top: 150px;
|
|
|
bottom: 50px;
|
|
bottom: 50px;
|
|
|
perspective: 500px;
|
|
perspective: 500px;
|
|
|
perspective-origin: 50% 50%;
|
|
perspective-origin: 50% 50%;
|
|
@@ -223,13 +58,22 @@ function handleMapPlayComplete() {
|
|
|
bottom: 0;
|
|
bottom: 0;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
- justify-content: space-between;
|
|
|
|
|
|
|
+ justify-content: flex-start;
|
|
|
|
|
+ gap: 20px;
|
|
|
transform: translate3d(0px, 0px, 0px) scaleX(1) scaleY(1) rotateX(0deg) rotateY(6deg) rotateZ(0deg) skewX(0deg) skewY(0deg);
|
|
transform: translate3d(0px, 0px, 0px) scaleX(1) scaleY(1) rotateX(0deg) rotateY(6deg) rotateZ(0deg) skewX(0deg) skewY(0deg);
|
|
|
z-index: 4;
|
|
z-index: 4;
|
|
|
}
|
|
}
|
|
|
.module-card {
|
|
.module-card {
|
|
|
|
|
+ height: 450px;
|
|
|
|
|
+ background: rgba(0, 20, 40, 0.8);
|
|
|
|
|
+ border: 1px solid rgba(48, 220, 255, 0.3);
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ box-shadow: 0 0 20px rgba(48, 220, 255, 0.1);
|
|
|
transform: translateX(-150%);
|
|
transform: translateX(-150%);
|
|
|
opacity: 0;
|
|
opacity: 0;
|
|
|
|
|
+ &:first-child {
|
|
|
|
|
+ margin-top: -50px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -238,7 +82,7 @@ function handleMapPlayComplete() {
|
|
|
z-index: 4;
|
|
z-index: 4;
|
|
|
width: 398px;
|
|
width: 398px;
|
|
|
right: 32px;
|
|
right: 32px;
|
|
|
- top: 126px;
|
|
|
|
|
|
|
+ top: 150px;
|
|
|
bottom: 50px;
|
|
bottom: 50px;
|
|
|
perspective: 800px;
|
|
perspective: 800px;
|
|
|
perspective-origin: 50% 50%;
|
|
perspective-origin: 50% 50%;
|
|
@@ -250,41 +94,21 @@ function handleMapPlayComplete() {
|
|
|
bottom: 0;
|
|
bottom: 0;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
- justify-content: space-between;
|
|
|
|
|
|
|
+ justify-content: flex-start;
|
|
|
|
|
+ gap: 20px;
|
|
|
transform: translate3d(0px, 0px, 0px) scaleX(1) scaleY(1) rotateX(0deg) rotateY(-6deg) rotateZ(0deg) skewX(0deg) skewY(0deg);
|
|
transform: translate3d(0px, 0px, 0px) scaleX(1) scaleY(1) rotateX(0deg) rotateY(-6deg) rotateZ(0deg) skewX(0deg) skewY(0deg);
|
|
|
}
|
|
}
|
|
|
.module-card {
|
|
.module-card {
|
|
|
|
|
+ height: 450px;
|
|
|
|
|
+ background: rgba(0, 20, 40, 0.8);
|
|
|
|
|
+ border: 1px solid rgba(48, 220, 255, 0.3);
|
|
|
|
|
+ border-radius: 10px;
|
|
|
|
|
+ box-shadow: 0 0 20px rgba(48, 220, 255, 0.1);
|
|
|
transform: translateX(150%);
|
|
transform: translateX(150%);
|
|
|
opacity: 0;
|
|
opacity: 0;
|
|
|
|
|
+ &:first-child {
|
|
|
|
|
+ margin-top: -30px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-.m-header {
|
|
|
|
|
- transform: translateY(-100%);
|
|
|
|
|
- opacity: 0;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.water-resource-left-zsline,
|
|
|
|
|
-.water-resource-right-zsline {
|
|
|
|
|
- position: absolute;
|
|
|
|
|
- top: 50%;
|
|
|
|
|
- transform: translateY(-50%);
|
|
|
|
|
- width: 30px;
|
|
|
|
|
- height: 60%;
|
|
|
|
|
- background-size: contain;
|
|
|
|
|
- background-repeat: no-repeat;
|
|
|
|
|
- opacity: 0.6;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.water-resource-left-zsline {
|
|
|
|
|
- left: 0;
|
|
|
|
|
- background-image: url("~@/assets/images/left-kuang.svg");
|
|
|
|
|
- background-position: left center;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-.water-resource-right-zsline {
|
|
|
|
|
- right: 0;
|
|
|
|
|
- background-image: url("~@/assets/images/right-kuang.svg");
|
|
|
|
|
- background-position: right center;
|
|
|
|
|
-}
|
|
|
|
|
</style>
|
|
</style>
|