提交 85481138 authored 作者: 詹银鑫's avatar 詹银鑫

添加左右侧收起展开

上级 f3c475d0
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1748918116226" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2010" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 2.373117C230.785632 2.373117 2.966396 230.192352 2.966396 511.406721S230.785632 1020.440324 512 1020.440324s509.033604-227.819235 509.033604-509.033603S793.214368 2.373117 512 2.373117z m186.289687 719.054461c15.425261 15.425261 15.425261 40.34299 0 55.768251L622.349942 853.135574a39.393743 39.393743 0 0 1-55.76825 0L331.643105 619.383546c-1.186559-1.186559-2.373117-1.186559-2.373117-2.373117l-77.126303-77.126304c-3.559676-3.559676-7.119351-8.30591-8.30591-13.052144-5.932793-14.238702-3.559676-32.03708 8.30591-42.716106l77.126303-77.126304c1.186559-1.186559 3.559676-3.559676 5.932793-4.746234l232.565469-232.565469c15.425261-15.425261 40.34299-15.425261 55.768251 0l77.126303 77.126303c15.425261 15.425261 15.425261 40.34299 0 55.768251L489.455388 511.406721l208.834299 210.020857z" p-id="2011" fill="#1296db"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1748917856818" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1450" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 2.373117C230.785632 2.373117 2.966396 230.192352 2.966396 511.406721S230.785632 1020.440324 512 1020.440324s509.033604-227.819235 509.033604-509.033603S793.214368 2.373117 512 2.373117z m259.856315 537.511008L695.91657 617.010429c-1.186559 1.186559-3.559676 3.559676-5.932792 4.746234L457.418308 853.135574a39.393743 39.393743 0 0 1-55.76825 0l-77.126304-77.126304a39.393743 39.393743 0 0 1 0-55.76825l208.834299-208.834299L325.710313 302.572422a39.393743 39.393743 0 0 1 0-55.768251l77.126303-77.126303c15.425261-15.425261 40.34299-15.425261 55.768251 0L693.543453 404.616454c1.186559 1.186559 2.373117 1.186559 2.373117 2.373117l77.126304 77.126304c3.559676 3.559676 7.119351 8.30591 8.305909 13.052144 4.746234 14.238702 2.373117 30.850521-9.492468 42.716106z" p-id="1451" fill="#1296db"></path></svg>
\ No newline at end of file
...@@ -126,6 +126,32 @@ body { ...@@ -126,6 +126,32 @@ body {
} }
} }
} }
.left-wrap-toggle {
position: absolute;
left: 430px;
top: 50%;
transform: translateY(-50%);
z-index: 10;
width: 24px; // 至少和img宽度一致或略大
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0 8px 8px 0;
cursor: pointer;
pointer-events: all;
opacity: 0;
transition: opacity 0.5s;
&.is-appear {
opacity: 1;
}
img {
width: 30px;
height: 30px;
object-fit: contain;
}
}
.right-wrap { .right-wrap {
position: absolute; position: absolute;
...@@ -153,6 +179,33 @@ body { ...@@ -153,6 +179,33 @@ body {
} }
} }
} }
.right-wrap-toggle {
position: absolute;
right: 430px;
top: 50%;
transform: translateY(-50%);
z-index: 10;
width: 24px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px 0 0 8px;
cursor: pointer;
pointer-events: all;
opacity: 0;
transition: opacity 0.5s;
&.is-appear {
opacity: 1;
}
img {
width: 30px;
height: 30px;
object-fit: contain;
transform: scaleX(-1); // 让箭头方向与左侧相反
}
}
.bottom-tray { .bottom-tray {
position: absolute; position: absolute;
left: 50%; left: 50%;
......
...@@ -3,14 +3,19 @@ ...@@ -3,14 +3,19 @@
<!-- 地图 --> <!-- 地图 -->
<mapScene ref="mapSceneRef"></mapScene> <mapScene ref="mapSceneRef"></mapScene>
<div class="large-screen-wrap" id="large-screen"> <div class="large-screen-wrap" id="large-screen">
<m-header title="准格尔旗环保一体化" sub-text="Guangdong Economic Visualization Platform"> <m-header
title="准格尔旗环保一体化"
sub-text="Guangdong Economic Visualization Platform"
>
<!--左侧 天气 --> <!--左侧 天气 -->
<template v-slot:left> <template v-slot:left>
<div class="m-header-weather"><span>小雨</span><span>27℃</span></div> <div class="m-header-weather"><span>小雨</span><span>27℃</span></div>
</template> </template>
<!--右侧 日期 --> <!--右侧 日期 -->
<template v-slot:right> <template v-slot:right>
<div class="m-header-date"><span>2023-10-12</span><span>17:53:16</span></div></template <div class="m-header-date">
<span>2023-10-12</span><span>17:53:16</span>
</div></template
> >
</m-header> </m-header>
<!-- 顶部菜单 --> <!-- 顶部菜单 -->
...@@ -27,10 +32,28 @@ ...@@ -27,10 +32,28 @@
</div> </div>
<!-- 顶部统计卡片 --> <!-- 顶部统计卡片 -->
<div class="top-count-card"> <div class="top-count-card">
<mCountCard v-for="(item, index) in state.totalView" :info="item" :key="index"></mCountCard> <mCountCard
v-for="(item, index) in state.totalView"
:info="item"
:key="index"
></mCountCard>
</div> </div>
<!-- 左边布局 图表 --> <!-- 左边布局 图表 -->
<div class="left-wrap"> <!-- 新增:left-wrap-toggle 箭头按钮 -->
<div
class="left-wrap-toggle"
:class="{
'is-appear': leftToggleAppear,
'is-hide': hideLeftChart,
}"
@click="toggleLeftChart"
>
<img
:src="hideLeftChart ? arrowRight : arrowLeft"
:alt="hideLeftChart ? '展开' : '收起'"
/>
</div>
<div class="left-wrap" v-show="!hideLeftChart">
<div class="left-wrap-3d"> <div class="left-wrap-3d">
<!-- 大宗商品销售额 --> <!-- 大宗商品销售额 -->
<BulkCommoditySalesChart></BulkCommoditySalesChart> <BulkCommoditySalesChart></BulkCommoditySalesChart>
...@@ -43,7 +66,21 @@ ...@@ -43,7 +66,21 @@
</div> </div>
</div> </div>
<!-- 右边布局 图表 --> <!-- 右边布局 图表 -->
<div class="right-wrap"> <div
class="right-wrap-toggle"
:class="{
'is-appear': rightToggleAppear,
'is-hide': hideRightChart,
}"
@click="toggleRightChart"
>
<img
:src="hideRightChart ? arrowRight : arrowLeft"
:alt="hideRightChart ? '展开' : '收起'"
/>
</div>
<!-- 右边布局 图表 -->
<div class="right-wrap" v-show="!hideRightChart">
<div class="right-wrap-3d"> <div class="right-wrap-3d">
<!-- 专项资金用途 --> <!-- 专项资金用途 -->
<PurposeSpecialFunds> </PurposeSpecialFunds> <PurposeSpecialFunds> </PurposeSpecialFunds>
...@@ -124,33 +161,37 @@ ...@@ -124,33 +161,37 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { shallowRef, ref, reactive, onMounted, onBeforeUnmount } from "vue" import { shallowRef, ref, reactive, onMounted, onBeforeUnmount } from "vue";
import mapScene from "./map.vue" import mapScene from "./map.vue";
import mHeader from "@/components/mHeader/index.vue" import mHeader from "@/components/mHeader/index.vue";
import mCountCard from "@/components/mCountCard/index.vue" import mCountCard from "@/components/mCountCard/index.vue";
import mMenu from "@/components/mMenu/index.vue" import mMenu from "@/components/mMenu/index.vue";
import mRadar from "@/components/mRadar/index.vue" import mRadar from "@/components/mRadar/index.vue";
import mMenuItem from "@/components/mMenuItem/index.vue" import mMenuItem from "@/components/mMenuItem/index.vue";
import mSvglineAnimation from "@/components/mSvglineAnimation/index.vue" import mSvglineAnimation from "@/components/mSvglineAnimation/index.vue";
import BulkCommoditySalesChart from "./components/BulkCommoditySalesChart.vue" import BulkCommoditySalesChart from "./components/BulkCommoditySalesChart.vue";
import YearlyEconomyTrend from "./components/YearlyEconomyTrend.vue" import YearlyEconomyTrend from "./components/YearlyEconomyTrend.vue";
import EconomicTrendChart from "./components/EconomicTrendChart.vue" import EconomicTrendChart from "./components/EconomicTrendChart.vue";
import DistrictEconomicIncome from "./components/DistrictEconomicIncome.vue" import DistrictEconomicIncome from "./components/DistrictEconomicIncome.vue";
import PurposeSpecialFunds from "./components/PurposeSpecialFunds.vue" import PurposeSpecialFunds from "./components/PurposeSpecialFunds.vue";
import ProportionPopulationConsumption from "./components/ProportionPopulationConsumption.vue" import ProportionPopulationConsumption from "./components/ProportionPopulationConsumption.vue";
import ElectricityUsage from "./components/ElectricityUsage.vue" import ElectricityUsage from "./components/ElectricityUsage.vue";
import QuarterlyGrowthSituation from "./components/QuarterlyGrowthSituation.vue" import QuarterlyGrowthSituation from "./components/QuarterlyGrowthSituation.vue";
import { Assets } from "./assets.js" import { Assets } from "./assets.js";
import emitter from "@/utils/emitter" import emitter from "@/utils/emitter";
import gsap from "gsap" import gsap from "gsap";
import autofit from "autofit.js" import autofit from "autofit.js";
// mqtt通信组件 // mqtt通信组件
import { mqttClient } from "@/utils/mqttClient" import { mqttClient } from "@/utils/mqttClient";
// 引入样式
import arrowLeft from "@/assets/images/arrow-left.svg";
import arrowRight from "@/assets/images/arrow-right.svg";
const assets = shallowRef(null) const assets = shallowRef(null);
const mapSceneRef = ref(null) const mapSceneRef = ref(null);
const state = reactive({ const state = reactive({
// 进度 // 进度
progress: 0, progress: 0,
...@@ -173,127 +214,143 @@ const state = reactive({ ...@@ -173,127 +214,143 @@ const state = reactive({
unit: "万人", unit: "万人",
}, },
], ],
}) });
const messages = ref([]) const messages = ref([]);
const inputMessage = ref('') const inputMessage = ref("");
// 隐藏左侧图表
const hideLeftChart = ref(false);
const leftToggleAppear = ref(false);
const hideRightChart = ref(false);
const rightToggleAppear = ref(false);
// 初始化连接 // 初始化连接
const connect = () => { const connect = () => {
mqttClient.connect() mqttClient.connect();
mqttClient.onMessage((topic, message) => { mqttClient.onMessage((topic, message) => {
messages.value.push(`[${topic}]: ${message}`) messages.value.push(`[${topic}]: ${message}`);
// 如果是 JSON 数据: // 如果是 JSON 数据:
// const data = JSON.parse(message) // const data = JSON.parse(message)
// 处理数据... // 处理数据...
}) });
} };
// 发送消息 // 发送消息
const sendMessage = () => { const sendMessage = () => {
if (inputMessage.value.trim()) { if (inputMessage.value.trim()) {
mqttClient.publish('your/topic', inputMessage.value) mqttClient.publish("your/topic", inputMessage.value);
inputMessage.value = '' inputMessage.value = "";
} }
} };
// 断开连接 // 断开连接
const disconnect = () => { const disconnect = () => {
mqttClient.disconnect() mqttClient.disconnect();
messages.value = [] messages.value = [];
} };
onMounted(() => { onMounted(() => {
// 连接mqtt // 连接mqtt
// connect() // connect()
// 监听地图播放完成,执行事件 // 监听地图播放完成,执行事件
emitter.$on("mapPlayComplete", handleMapPlayComplete) emitter.$on("mapPlayComplete", handleMapPlayComplete);
// 自动适配 // 自动适配
assets.value = autofit.init({ assets.value = autofit.init({
dh: 1080, dh: 1080,
dw: 1920, dw: 1920,
el: "#large-screen", el: "#large-screen",
resize: true, resize: true,
}) });
// 初始化资源 // 初始化资源
initAssets(async () => { initAssets(async () => {
// 加载地图 // 加载地图
emitter.$emit("loadMap", assets.value) emitter.$emit("loadMap", assets.value);
// 隐藏loading // 隐藏loading
await hideLoading() await hideLoading();
// 播放场景 // 播放场景
mapSceneRef.value.play() mapSceneRef.value.play();
}) });
}) });
onBeforeUnmount(() => { onBeforeUnmount(() => {
emitter.$off("mapPlayComplete", handleMapPlayComplete) emitter.$off("mapPlayComplete", handleMapPlayComplete);
// 断开mqtt连接 // 断开mqtt连接
disconnect() disconnect();
}) });
// 初始化加载资源 // 初始化加载资源
function initAssets(onLoadCallback) { function initAssets(onLoadCallback) {
assets.value = new Assets() assets.value = new Assets();
// 资源加载进度 // 资源加载进度
let params = { let params = {
progress: 0, progress: 0,
} };
assets.value.instance.on("onProgress", (path, itemsLoaded, itemsTotal) => { assets.value.instance.on("onProgress", (path, itemsLoaded, itemsTotal) => {
let p = Math.floor((itemsLoaded / itemsTotal) * 100) let p = Math.floor((itemsLoaded / itemsTotal) * 100);
gsap.to(params, { gsap.to(params, {
progress: p, progress: p,
onUpdate: () => { onUpdate: () => {
state.progress = Math.floor(params.progress) state.progress = Math.floor(params.progress);
}, },
}) });
}) });
// 资源加载完成 // 资源加载完成
assets.value.instance.on("onLoad", () => { assets.value.instance.on("onLoad", () => {
onLoadCallback && onLoadCallback() onLoadCallback && onLoadCallback();
}) });
} }
// 隐藏loading // 隐藏loading
async function hideLoading() { async function hideLoading() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let tl = gsap.timeline() let tl = gsap.timeline();
tl.to(".loading-text span", { tl.to(".loading-text span", {
y: "200%", y: "200%",
opacity: 0, opacity: 0,
ease: "power4.inOut", ease: "power4.inOut",
duration: 2, duration: 2,
stagger: 0.2, stagger: 0.2,
}) });
tl.to(".loading-progress", { opacity: 0, ease: "power4.inOut", duration: 2 }, "<") tl.to(
".loading-progress",
{ opacity: 0, ease: "power4.inOut", duration: 2 },
"<"
);
tl.to( tl.to(
".loading", ".loading",
{ {
opacity: 0, opacity: 0,
ease: "power4.inOut", ease: "power4.inOut",
onComplete: () => { onComplete: () => {
resolve() resolve();
}, },
}, },
"-=1" "-=1"
) );
}) });
} }
function handleMenuSelect(index) { function handleMenuSelect(index) {
state.activeIndex = index state.activeIndex = index;
} }
// 地图开始动画播放完成 // 地图开始动画播放完成
function handleMapPlayComplete() { function handleMapPlayComplete() {
let tl = gsap.timeline({ paused: false }) let tl = gsap.timeline({ paused: false });
let leftCards = gsap.utils.toArray(".left-card") let leftCards = gsap.utils.toArray(".left-card");
let rightCards = gsap.utils.toArray(".right-card") let rightCards = gsap.utils.toArray(".right-card");
let countCards = gsap.utils.toArray(".count-card") let countCards = gsap.utils.toArray(".count-card");
tl.addLabel("start", 0.5) tl.addLabel("start", 0.5);
tl.addLabel("menu", 0.5) tl.addLabel("menu", 0.5);
tl.addLabel("card", 1) tl.addLabel("card", 1);
tl.addLabel("countCard", 3) tl.addLabel("countCard", 3);
tl.to(".m-header", { y: 0, opacity: 1, duration: 1.5, ease: "power4.out" }, "start") tl.to(
tl.to(".bottom-tray", { y: 0, opacity: 1, duration: 1.5, ease: "power4.out" }, "start") ".m-header",
{ y: 0, opacity: 1, duration: 1.5, ease: "power4.out" },
"start"
);
tl.to(
".bottom-tray",
{ y: 0, opacity: 1, duration: 1.5, ease: "power4.out" },
"start"
);
tl.to( tl.to(
".top-menu", ".top-menu",
{ {
...@@ -303,10 +360,22 @@ function handleMapPlayComplete() { ...@@ -303,10 +360,22 @@ function handleMapPlayComplete() {
ease: "power4.out", ease: "power4.out",
}, },
"-=1" "-=1"
) );
tl.to(".bottom-radar", { y: 0, opacity: 1, duration: 1.5, ease: "power4.out" }, "-=2") tl.to(
tl.to(leftCards, { x: 0, opacity: 1, stagger: 0.2, duration: 1.5, ease: "power4.out" }, "card") ".bottom-radar",
tl.to(rightCards, { x: 0, opacity: 1, stagger: 0.2, duration: 1.5, ease: "power4.out" }, "card") { y: 0, opacity: 1, duration: 1.5, ease: "power4.out" },
"-=2"
);
tl.to(
leftCards,
{ x: 0, opacity: 1, stagger: 0.2, duration: 1.5, ease: "power4.out" },
"card"
);
tl.to(
rightCards,
{ x: 0, opacity: 1, stagger: 0.2, duration: 1.5, ease: "power4.out" },
"card"
);
tl.to( tl.to(
countCards, countCards,
{ {
...@@ -317,7 +386,73 @@ function handleMapPlayComplete() { ...@@ -317,7 +386,73 @@ function handleMapPlayComplete() {
ease: "power4.out", ease: "power4.out",
}, },
"card" "card"
) );
tl.to(
".left-wrap-toggle",
{
opacity: 1,
x: 0,
left: 430,
duration: 1,
ease: "power4.out",
onStart: () => {
leftToggleAppear.value = true;
},
},
"card"
);
tl.to(
".right-wrap-toggle",
{
opacity: 1,
x: 0,
right: 430,
duration: 1,
ease: "power4.out",
onStart: () => {
rightToggleAppear.value = true;
},
},
"card"
);
}
// 切换左侧图表显示隐藏
function toggleLeftChart() {
hideLeftChart.value = !hideLeftChart.value;
if (hideLeftChart.value) {
// 收起时滑到最左侧
gsap.to(".left-wrap-toggle", {
left: 10,
duration: 0.5,
ease: "power2.inOut",
});
} else {
// 展开时滑回原位
gsap.to(".left-wrap-toggle", {
left: 430,
duration: 0.5,
ease: "power2.inOut",
});
}
}
// 切换右侧图表显示隐藏
function toggleRightChart() {
hideRightChart.value = !hideRightChart.value;
if (hideRightChart.value) {
// 收起时滑到最右侧
gsap.to(".right-wrap-toggle", {
right: 10,
duration: 0.5,
ease: "power2.inOut",
});
} else {
// 展开时滑回原位
gsap.to(".right-wrap-toggle", {
right: 430,
duration: 0.5,
ease: "power2.inOut",
});
}
} }
</script> </script>
......
...@@ -67,6 +67,11 @@ export default ({ mode }) => { ...@@ -67,6 +67,11 @@ export default ({ mode }) => {
} }
} }
}, },
server: {
host: '0.0.0.0',
port: 8080,
open: true,
},
envDir: 'env', envDir: 'env',
plugins: [vue()], plugins: [vue()],
}); });
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论