feat:代码提交
This commit is contained in:
parent
9b1f30f563
commit
5ba539ddcc
166
src/App.vue
166
src/App.vue
|
|
@ -17,7 +17,7 @@
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<Left @updateData="handleUpdateData" />
|
<Left @updateData="handleUpdateData" />
|
||||||
<div class="map-content">
|
<div class="map-content">
|
||||||
<div v-show="show" class="data" :style="{ left: left - 327 + 'px', top: top - 286 + 'px' }">
|
<div v-show="showa" class="data" :style="{ left: left - 327 + 'px', top: top - 286 + 'px' }">
|
||||||
<div class="data-t">道路基本信息</div>
|
<div class="data-t">道路基本信息</div>
|
||||||
<div class="data-v">
|
<div class="data-v">
|
||||||
<div class="item" style="width: 70%; margin-bottom: 12px">
|
<div class="item" style="width: 70%; margin-bottom: 12px">
|
||||||
|
|
@ -43,39 +43,164 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="width: 100%;height: 100%;position: relative;">
|
<div style="width: 100%;height: 100%;position: relative;">
|
||||||
<img
|
<div>
|
||||||
|
<canvas
|
||||||
|
v-show="show"
|
||||||
|
ref="mapCanvas"
|
||||||
|
width="800"
|
||||||
|
height="600"
|
||||||
|
@click="handleCanvasClick"
|
||||||
|
style="margin-top: 150px;margin-left: 80px;"
|
||||||
|
></canvas>
|
||||||
|
<img
|
||||||
|
v-show="showa"
|
||||||
|
src="@/assets/imgs/hy.png"
|
||||||
|
alt
|
||||||
|
style="width: 800px;height:600px;margin-top: 150px;margin-left: 80px;"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-show="showb"
|
||||||
|
src="@/assets/imgs/yx.png"
|
||||||
|
alt
|
||||||
|
style="width: 800px;height:600px;margin-top: 150px;margin-left: 80px;"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-show="showc"
|
||||||
|
src="@/assets/imgs/snl.png"
|
||||||
|
alt
|
||||||
|
style="width: 800px;height:600px;margin-top: 150px;margin-left: 80px;"
|
||||||
|
/>
|
||||||
|
<!-- 使用 Element Plus 的 Dialog -->
|
||||||
|
<el-dialog v-model="showDialog" title="桩号信息" :width="dialogWidth" @close="closeDialog">
|
||||||
|
<p>起点桩号: 35.580</p>
|
||||||
|
<p>距离道路终点: 20KM</p>
|
||||||
|
<!-- <p>起点桩号: 35.580</p> -->
|
||||||
|
<!-- <template #footer>
|
||||||
|
<el-button @click="closeDialog">Close</el-button>
|
||||||
|
</template>-->
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
<!-- <img
|
||||||
v-if="!show"
|
v-if="!show"
|
||||||
src="@/assets/imgs/ditua.png"
|
src="@/assets/imgs/ditua.png"
|
||||||
alt
|
alt
|
||||||
style="width: 86%;height: 60%;margin-top: 150px;margin-left: 80px;"
|
style="width: 86%;height: 60%;margin-top: 150px;margin-left: 80px;"
|
||||||
/>
|
/>-->
|
||||||
<img
|
|
||||||
v-else
|
<div class="other1" @click="showa = false;showb = false;showc = false;show=true" v-if="show==false">
|
||||||
src="@/assets/imgs/hy.png"
|
|
||||||
alt
|
|
||||||
style="width: 86%;height: 60%;margin-top: 150px;margin-left: 80px;"
|
|
||||||
/>
|
|
||||||
<div class="other1" @click="show = false" v-if="show">
|
|
||||||
<!-- <Icon :size="14" icon="svg-icon:cd" /> -->
|
<!-- <Icon :size="14" icon="svg-icon:cd" /> -->
|
||||||
<span>返回</span>
|
<span>返回</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- <Right @updateData="handleUpdateData" /> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
import PHeader from "./components/PHeader/index.vue";
|
import PHeader from "./components/PHeader/index.vue";
|
||||||
import Left from "./components/Left.vue";
|
import Left from "./components/Left.vue";
|
||||||
|
// import Right from "./components/Right.vue";
|
||||||
|
import amg from "@/assets/imgs/ditua.png";
|
||||||
|
|
||||||
import { ref } from "vue";
|
// import { ref } from "vue";
|
||||||
|
|
||||||
|
const show = ref(true);
|
||||||
|
const showa = ref(false);
|
||||||
|
const showb = ref(false);
|
||||||
|
const showc = ref(false);
|
||||||
|
|
||||||
const show = ref(false);
|
|
||||||
const input1 = ref("");
|
|
||||||
const handleUpdateData = data => {
|
const handleUpdateData = data => {
|
||||||
show.value = true;
|
if(data == "海岳大街") {
|
||||||
|
showa.value = true;
|
||||||
|
show.value = false;
|
||||||
|
showb.value = false;
|
||||||
|
showc.value = false;
|
||||||
|
}else if(data == "雄县") {
|
||||||
|
show.value = false;
|
||||||
|
showa.value = false;
|
||||||
|
showb.value = true;
|
||||||
|
showc.value = false;
|
||||||
|
}else if(data == "水泥路") {
|
||||||
|
show.value = false;
|
||||||
|
showa.value = false;
|
||||||
|
showb.value = false;
|
||||||
|
showc.value = true;
|
||||||
|
}else if(data == "2024") {
|
||||||
|
show.value = false;
|
||||||
|
showa.value = false;
|
||||||
|
showb.value = false;
|
||||||
|
showc.value = true;
|
||||||
|
}else if(data == "2025") {
|
||||||
|
show.value = true;
|
||||||
|
showa.value = false;
|
||||||
|
showb.value = false;
|
||||||
|
showc.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
import { ref, onMounted } from "vue";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
|
const mapCanvas = ref(null);
|
||||||
|
const showDialog = ref(false);
|
||||||
|
const clickedPoint = ref({ x: null, y: null });
|
||||||
|
|
||||||
|
const dialogWidth = "20%"; // 设置对话框宽度
|
||||||
|
const points = [
|
||||||
|
{ x: 320, y: 200 },
|
||||||
|
{ x: 600, y: 400 }
|
||||||
|
];
|
||||||
|
onMounted(() => {
|
||||||
|
const canvas = mapCanvas.value;
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
|
// 绘制背景图片
|
||||||
|
const image = new Image();
|
||||||
|
image.src = amg;
|
||||||
|
image.onload = () => {
|
||||||
|
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
// 绘制标记点
|
||||||
|
points.forEach(point => {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(point.x, point.y, 5, 0, Math.PI * 2);
|
||||||
|
ctx.fillStyle = "red";
|
||||||
|
ctx.fill();
|
||||||
|
ctx.closePath();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle canvas click and check if a point was clicked
|
||||||
|
const handleCanvasClick = event => {
|
||||||
|
const canvas = mapCanvas.value;
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
const x = event.clientX - rect.left;
|
||||||
|
const y = event.clientY - rect.top;
|
||||||
|
console.log(x, y, ":::::::");
|
||||||
|
|
||||||
|
// Check if the click is near any point
|
||||||
|
let clicked = false;
|
||||||
|
points.forEach(point => {
|
||||||
|
const distance = Math.sqrt((x - point.x) ** 2 + (y - point.y) ** 2);
|
||||||
|
if (distance < 10) {
|
||||||
|
// threshold distance to register click
|
||||||
|
clickedPoint.value = point;
|
||||||
|
showDialog.value = true;
|
||||||
|
clicked = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!clicked) {
|
||||||
|
ElMessage.warning("请正确选择标记点");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Close dialog
|
||||||
|
const closeDialog = () => {
|
||||||
|
showDialog.value = false;
|
||||||
};
|
};
|
||||||
// const leftRef = ref()
|
// const leftRef = ref()
|
||||||
// onMounted(() => {
|
// onMounted(() => {
|
||||||
|
|
@ -84,6 +209,10 @@ const handleUpdateData = data => {
|
||||||
// })
|
// })
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
canvas {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
.home {
|
.home {
|
||||||
height: 1000px;
|
height: 1000px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -149,7 +278,10 @@ const handleUpdateData = data => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
:deep(.el-input-group__prepend) {
|
||||||
|
color:#ffffff;
|
||||||
|
background: linear-gradient(270deg, #139fd5 0%, #20d6ad 100%, #5cf3d1 100%);
|
||||||
|
}
|
||||||
.other {
|
.other {
|
||||||
height: 26px;
|
height: 26px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
@ -168,7 +300,7 @@ const handleUpdateData = data => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.other1 {
|
.other1 {
|
||||||
position:absolute;
|
position: absolute;
|
||||||
right: -40px;
|
right: -40px;
|
||||||
top: 100px;
|
top: 100px;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 303 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 302 KiB |
|
|
@ -1,6 +1,23 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div>
|
<div>
|
||||||
|
<div style="display: flex;align-items: center;">
|
||||||
|
<div class="other1">
|
||||||
|
<!-- <Icon :size="14" icon="svg-icon:cd" /> -->
|
||||||
|
<span>年份筛选</span>
|
||||||
|
</div>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="year"
|
||||||
|
:type="radio1"
|
||||||
|
:editable='false'
|
||||||
|
value-format="YYYY"
|
||||||
|
:clearable="false"
|
||||||
|
placeholder="请选择"
|
||||||
|
style="max-width: 600px;margin-bottom:30px"
|
||||||
|
@change="searchd(year)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="input1"
|
v-model="input1"
|
||||||
style="max-width: 600px;margin-left: 40px;margin-top: -18px;margin-bottom:10px"
|
style="max-width: 600px;margin-left: 40px;margin-top: -18px;margin-bottom:10px"
|
||||||
|
|
@ -11,7 +28,28 @@
|
||||||
<el-button @click="search(input1)">查询</el-button>
|
<el-button @click="search(input1)">查询</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<img src="@/assets/imgs/dituc.png" alt style="width: 100%;height: 100%;margin-left: 40px;" />
|
<el-input
|
||||||
|
v-model="input2"
|
||||||
|
style="max-width: 600px;margin-left: 40px;margin-bottom:10px"
|
||||||
|
placeholder="雄县"
|
||||||
|
>
|
||||||
|
<template #prepend>行政等级</template>
|
||||||
|
<template #append>
|
||||||
|
<el-button @click="searchb(input2)">查询</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<el-input
|
||||||
|
v-model="input3"
|
||||||
|
style="max-width: 600px;margin-left: 40px;margin-bottom:10px"
|
||||||
|
placeholder="水泥路"
|
||||||
|
>
|
||||||
|
<template #prepend>道路类型</template>
|
||||||
|
<template #append>
|
||||||
|
<el-button @click="searchc(input3)">查询</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
|
||||||
|
<img src="@/assets/imgs/dituc.png" alt style="width: 100%;height: 90%;margin-left: 40px;" />
|
||||||
</div>
|
</div>
|
||||||
<!-- <LeftTwo ref="leftTwoRef" />
|
<!-- <LeftTwo ref="leftTwoRef" />
|
||||||
<LeftThree ref="leftThreeRef" />-->
|
<LeftThree ref="leftThreeRef" />-->
|
||||||
|
|
@ -19,8 +57,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, defineExpose, reactive } from "vue";
|
import { ref, defineExpose, reactive, onMounted } from "vue";
|
||||||
import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
|
|
||||||
|
import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
|
||||||
// import Tit from "./Tit/index.vue";
|
// import Tit from "./Tit/index.vue";
|
||||||
// import * as CockpitApi from '@/api/cockpit'
|
// import * as CockpitApi from '@/api/cockpit'
|
||||||
// import Tit
|
// import Tit
|
||||||
|
|
@ -29,9 +68,18 @@ const loading = ref(false);
|
||||||
const loaded = ref(false);
|
const loaded = ref(false);
|
||||||
const percentage = ref();
|
const percentage = ref();
|
||||||
const input1 = ref("");
|
const input1 = ref("");
|
||||||
|
const input2 = ref("");
|
||||||
|
const input3 = ref("");
|
||||||
|
const year = ref("");
|
||||||
|
const radio1 = ref("year");
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
// seriesData: {}
|
// seriesData: {}
|
||||||
});
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
year.value = String(new Date().getFullYear());
|
||||||
|
// value.value = String(new Date().getFullYear())
|
||||||
|
// search()
|
||||||
|
});
|
||||||
|
|
||||||
// const percentage = computed(() => {
|
// const percentage = computed(() => {
|
||||||
// return (state.seriesData.lastYearEmissions / state.seriesData.lastYearTarget) * 100 >= 100
|
// return (state.seriesData.lastYearEmissions / state.seriesData.lastYearTarget) * 100 >= 100
|
||||||
|
|
@ -51,6 +99,43 @@ const search = data => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const searchb = data => {
|
||||||
|
// getData(data)
|
||||||
|
if (data == "雄县") {
|
||||||
|
emit("updateData", data);
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
message: "抱歉,暂无行政区信息",
|
||||||
|
type: "warning",
|
||||||
|
plain: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const searchc = data => {
|
||||||
|
// getData(data)
|
||||||
|
if (data == "水泥路") {
|
||||||
|
emit("updateData", data);
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
message: "抱歉,暂无道路类型",
|
||||||
|
type: "warning",
|
||||||
|
plain: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const searchd = data => {
|
||||||
|
// getData(data)
|
||||||
|
// if (data == "2024") {
|
||||||
|
emit("updateData", data);
|
||||||
|
// } else {
|
||||||
|
// ElMessage({
|
||||||
|
// message: "抱歉,暂无道路类型",
|
||||||
|
// type: "warning",
|
||||||
|
// plain: true
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
// const searchb
|
||||||
|
|
||||||
// search()
|
// search()
|
||||||
|
|
||||||
|
|
@ -64,9 +149,33 @@ defineExpose({
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 438px;
|
width: 438px;
|
||||||
left: 30px;
|
left: 30px;
|
||||||
top: 125px;
|
top: 75px;
|
||||||
|
}
|
||||||
|
.other1 {
|
||||||
|
// position: absolute;
|
||||||
|
// right: -40px;
|
||||||
|
// top: 100px;
|
||||||
|
margin-left: 40px;
|
||||||
|
margin-bottom:30px;
|
||||||
|
height: 31x;
|
||||||
|
line-height: 31px;
|
||||||
|
width: 96px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 12px 0 12px;
|
||||||
|
background: linear-gradient(270deg, #139fd5 0%, #20d6ad 100%, #5cf3d1 100%);
|
||||||
|
border-radius: 2px;
|
||||||
|
// margin-right: 9px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #ffffff;
|
||||||
|
text-align: center;
|
||||||
|
// display: flex;
|
||||||
|
// align-items: center;
|
||||||
|
// justify-content: space-between;
|
||||||
|
cursor: pointer;
|
||||||
|
:deep(.v-icon) {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.leftOne-content {
|
.leftOne-content {
|
||||||
padding: 0 73px 0 43px;
|
padding: 0 73px 0 43px;
|
||||||
width: 340px;
|
width: 340px;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,173 @@
|
||||||
|
<template>
|
||||||
|
<div class="right">
|
||||||
|
<div>
|
||||||
|
|
||||||
|
|
||||||
|
<img src="@/assets/imgs/dituc.png" alt style="width: 100%;height: 90%;margin-left: 40px;" />
|
||||||
|
</div>
|
||||||
|
<!-- <LeftTwo ref="leftTwoRef" />
|
||||||
|
<LeftThree ref="leftThreeRef" />-->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, defineExpose, reactive, onMounted } from "vue";
|
||||||
|
|
||||||
|
import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
|
||||||
|
// import Tit from "./Tit/index.vue";
|
||||||
|
// import * as CockpitApi from '@/api/cockpit'
|
||||||
|
// import Tit
|
||||||
|
const emit = defineEmits(["updateData"]);
|
||||||
|
const loading = ref(false);
|
||||||
|
const loaded = ref(false);
|
||||||
|
const percentage = ref();
|
||||||
|
const input1 = ref("");
|
||||||
|
const year = ref("");
|
||||||
|
const radio1 = ref("year");
|
||||||
|
const state = reactive({
|
||||||
|
// seriesData: {}
|
||||||
|
});
|
||||||
|
onMounted(() => {
|
||||||
|
year.value = String(new Date().getFullYear());
|
||||||
|
// value.value = String(new Date().getFullYear())
|
||||||
|
// search()
|
||||||
|
});
|
||||||
|
|
||||||
|
// const percentage = computed(() => {
|
||||||
|
// return (state.seriesData.lastYearEmissions / state.seriesData.lastYearTarget) * 100 >= 100
|
||||||
|
// ? 100
|
||||||
|
// : (state.seriesData.lastYearEmissions / state.seriesData.lastYearTarget) * 100 || 0
|
||||||
|
// })
|
||||||
|
|
||||||
|
const search = data => {
|
||||||
|
// getData(data)
|
||||||
|
if (data == "海岳大街") {
|
||||||
|
emit("updateData", data);
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
message: "抱歉,暂时无道路信息",
|
||||||
|
type: "warning",
|
||||||
|
plain: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// search()
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
search
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.right {
|
||||||
|
position: absolute;
|
||||||
|
width: 440px;
|
||||||
|
right: 80px;
|
||||||
|
top: 127px;
|
||||||
|
}
|
||||||
|
.other1 {
|
||||||
|
// position: absolute;
|
||||||
|
// right: -40px;
|
||||||
|
// top: 100px;
|
||||||
|
margin-left: 40px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
height: 31x;
|
||||||
|
line-height: 31px;
|
||||||
|
width: 96px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 12px 0 12px;
|
||||||
|
background: linear-gradient(270deg, #139fd5 0%, #20d6ad 100%, #5cf3d1 100%);
|
||||||
|
border-radius: 2px;
|
||||||
|
// margin-right: 9px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #ffffff;
|
||||||
|
text-align: center;
|
||||||
|
// display: flex;
|
||||||
|
// align-items: center;
|
||||||
|
// justify-content: space-between;
|
||||||
|
cursor: pointer;
|
||||||
|
:deep(.v-icon) {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.leftOne-content {
|
||||||
|
padding: 0 73px 0 43px;
|
||||||
|
width: 340px;
|
||||||
|
height: 800px;
|
||||||
|
background-color: #05151a;
|
||||||
|
color: aliceblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-family: SourceHanSansCN;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #c6d8e4;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
padding-top: 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
font-family: Bebas;
|
||||||
|
font-size: 32px;
|
||||||
|
color: transparent;
|
||||||
|
background: linear-gradient(180deg, #3ff1b6 0%, #08dae8 100%);
|
||||||
|
background-clip: text;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value-pre {
|
||||||
|
font-family: Bebas;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #cedce6;
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value-text {
|
||||||
|
&-l {
|
||||||
|
margin-right: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-v {
|
||||||
|
font-size: 20px;
|
||||||
|
font-family: Bebas;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.total {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-label {
|
||||||
|
font-family: SourceHanSansCN;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #c6d8e4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-value {
|
||||||
|
font-family: Bebas;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #cedce6;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-value-pre {
|
||||||
|
font-family: Bebas;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #cedce6;
|
||||||
|
margin-left: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// :deep(.el-progress-bar__inner) {
|
||||||
|
// background: linear-gradient(90deg, #00fdc7 0%, #0dc2ff 100%);
|
||||||
|
// }
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<canvas ref="canvas" @click="handleCanvasClick"></canvas>
|
||||||
|
<div v-if="showPopup" class="popup" :style="popupStyle">
|
||||||
|
<p>{{ popupContent }}</p >
|
||||||
|
<button @click="closePopup">关闭</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const canvas = ref(null);
|
||||||
|
const showPopup = ref(false);
|
||||||
|
const popupContent = ref('');
|
||||||
|
const popupStyle = ref({});
|
||||||
|
const markers = ref([]);
|
||||||
|
|
||||||
|
const imageUrl = 'your-image-url.jpg'; // 替换为你的图片URL
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const ctx = canvas.value.getContext('2d');
|
||||||
|
const img = new Image();
|
||||||
|
img.src = imageUrl;
|
||||||
|
img.onload = () => {
|
||||||
|
canvas.value.width = img.width;
|
||||||
|
canvas.value.height = img.height;
|
||||||
|
ctx.drawImage(img, 0, 0);
|
||||||
|
|
||||||
|
// 绘制标记点
|
||||||
|
markers.value.forEach(marker => {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(marker.x, marker.y, 5, 0, 2 * Math.PI);
|
||||||
|
ctx.fillStyle = 'red';
|
||||||
|
ctx.fill();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleCanvasClick = (event) => {
|
||||||
|
const rect = canvas.value.getBoundingClientRect();
|
||||||
|
const x = event.clientX - rect.left;
|
||||||
|
const y = event.clientY - rect.top;
|
||||||
|
|
||||||
|
// 检查是否点击了标记点
|
||||||
|
const clickedMarker = markers.value.find(marker => {
|
||||||
|
const dx = marker.x - x;
|
||||||
|
const dy = marker.y - y;
|
||||||
|
return Math.sqrt(dx * dx + dy * dy) < 5; // 5是标记点的半径
|
||||||
|
});
|
||||||
|
|
||||||
|
if (clickedMarker) {
|
||||||
|
showPopup.value = true;
|
||||||
|
popupContent.value = clickedMarker.info;
|
||||||
|
popupStyle.value = {
|
||||||
|
left: `${clickedMarker.x + rect.left}px`,
|
||||||
|
top: `${clickedMarker.y + rect.top}px`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const closePopup = () => {
|
||||||
|
showPopup.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
canvas,
|
||||||
|
showPopup,
|
||||||
|
popupContent,
|
||||||
|
popupStyle,
|
||||||
|
handleCanvasClick,
|
||||||
|
closePopup,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.popup {
|
||||||
|
position: absolute;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue