鼠标地图多选框选、地图工具复制、地图工具粘贴、地图工具删除、地图工具文字输入
This commit is contained in:
parent
9d0cc0b096
commit
325de2cc64
@ -90,6 +90,18 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
|||||||
icon: 'ep:edit',
|
icon: 'ep:edit',
|
||||||
title: '地图编辑'
|
title: '地图编辑'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'test',
|
||||||
|
component: () => import('@/views/mapPage/realTimeMap/test.vue'),
|
||||||
|
name: 'testMapPageRealTimeMap',
|
||||||
|
meta: {
|
||||||
|
noCache: true, // 需要缓存
|
||||||
|
hidden: true,
|
||||||
|
canTo: true,
|
||||||
|
icon: 'ep:edit',
|
||||||
|
title: '测试'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="dialogFormVisible" title="节点属性" width="540">
|
<Dialog v-model="dialogFormVisible" title="节点属性" width="540" class="node-form-dialog">
|
||||||
<el-form :model="form" label-width="75">
|
<el-form :model="form" label-width="auto">
|
||||||
<el-form-item label="X" prop="locationX" required>
|
<el-form-item label="X" prop="locationX" required>
|
||||||
<el-input v-model="form.locationX" placeholder="请输入" />
|
<el-input v-model="form.locationX" placeholder="请输入" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -99,7 +99,7 @@
|
|||||||
<el-button type="primary" @click="submit"> 确认 </el-button>
|
<el-button type="primary" @click="submit"> 确认 </el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -212,3 +212,15 @@ const deviceTypeChange = () => {
|
|||||||
|
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.node-form-dialog {
|
||||||
|
.el-dialog__header {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__footer {
|
||||||
|
border-top: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogFormVisible" title="文字设置" width="400" class="text-form-dialog">
|
||||||
|
<el-form :model="form">
|
||||||
|
<el-form-item label="字体">
|
||||||
|
<el-select v-model="form.fontType" placeholder="请选择">
|
||||||
|
<el-option label="宋体" value="SimSun" />
|
||||||
|
<el-option label="黑体" value="SimHei" />
|
||||||
|
<el-option label="微软雅黑" value="Microsoft Yahei" />
|
||||||
|
<el-option label="楷体" value="KaiTi" />
|
||||||
|
<el-option label="新宋体" value="NSimSun" />
|
||||||
|
<el-option label="仿宋" value="FangSong" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="字号">
|
||||||
|
<el-input-number
|
||||||
|
v-model="form.fontSize"
|
||||||
|
:step="1"
|
||||||
|
:min="10"
|
||||||
|
:max="30"
|
||||||
|
placeholder="请输入"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="颜色">
|
||||||
|
<el-color-picker v-model="form.fontColor" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="dialogFormVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="dialogFormVisible = false"> 确认 </el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
|
||||||
|
const dialogFormVisible = ref(false)
|
||||||
|
const formLabelWidth = '140px'
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
fontType: 'SimSun',
|
||||||
|
fontSize: '14',
|
||||||
|
fontColor: '#000000'
|
||||||
|
})
|
||||||
|
|
||||||
|
const open = (item) => {
|
||||||
|
dialogFormVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.text-form-dialog {
|
||||||
|
.el-dialog__header {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__footer {
|
||||||
|
border-top: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
6
src/views/mapPage/realTimeMap/cursorCollection.js
Normal file
6
src/views/mapPage/realTimeMap/cursorCollection.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
let cursorCollection = {
|
||||||
|
node: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAAXNSR0IArs4c6QAACv9JREFUeF7tnTuobdUVhn/R2iopJDEGtDABtTBFUqiFoBG9hU1ioSCIDzApEvIoLMTCIhpiEQM+EAQtTBqLqxgFC7XQwhQqJCkU8hILrayVZI3cdRGPZ5899txzPfb4v9ncW8zX+P75n7XXXPNxjkgQgMBGAufABgIQ2EwAgzA6IHACAQzC8IAABmEMQKCNAE+QNm6UMiGAQUyEJsw2AhikjRulTAhgEBOhCbONAAZp40YpEwIYxERowmwjgEHauFHKhAAGMRGaMNsIYJA2bpQyIYBBTIQmzDYCGKSNG6VMCGAQE6EJs40ABmnjRikTAhjERGjCbCOAQdq4UcqEAAYxEZow2whgkDZulDIhgEFMhCbMNgIYpI0bpUwIYBAToQmzjQAGaeNGKRMCGMREaMJsI4BB2rhRyoQABjERmjDbCGCQNm6UMiGAQUyEJsw2AhikjRulTAhgEBOhCbONAAZp40YpEwIYxERowmwjgEHauFHKhAAGMRGaMNsIYJA2bpQyIYBBTIQmzDYCGKSNG6VMCGAQE6EJs40ABmnjRikTAhjERGjCbCOAQdq4UcqEAAYxEZow2whgkDZulDIhgEFMhCbMNgIYpI0bpUwIYBAToQmzjQAGaeNGKRMCGGQ+ob8h6TJJ35F0saSLJF0g6Wvj/4/ryT8lfSLpI0nx/w8k/U3Se5I+nK/rvi1hkOm0DyNcK+kqST+QdGHnpv4t6c2hjTeGNl4djdO5CarDIH3HwPcl3Szp1Pik6Fv7ybXFk+W0pOclvTVnw5XbwiD7qxs/kW6XdIekS/evrksNfx+eWE9Jenr8idalUsdKMEi76vE+ce/wfnB3exWzlHxc0h/G95ZZGqzUCAbZXc3LJf1S0q27F120xLOSHpb07qK9OLDGMUhesK9Lun98auRLrS9nPE0eGOL4eH1dW1+PMEhOk59IelDS+bnsq8/1qaT7hinmR1ff04U7iEFOFuC7kh6RdN3COk3V/CuSfibpr1M1cOj1YpDNCsbLd/yFPe/QRd7S/8/Hn43xMk86QgCDHD8kYrDcZTZanjSMeavEGOTLiGL5xzPj1++t8ApmiK/yt43LWgqGt3tIGOQLZvEV/LkT1kXtTvcwS8Sar1v4Gn9GPAxyhkO8hL98mON5sl5fLyle4q0TBpFulPSC9SjYHPxNkl50ZuNuEJ4c20e/9ZPE2SDxzhHLxUnbCcRyfcsVwq4Gidmq13gh3+6MMUe8uF/jOLvlapDXjady0644kjGmgK9uLXyo5RwN8sSwXfXOQxVs4X4Hu7Uv7++KyM0gIe5jXQn6VXbPsJfeZlmKk0Fi4WHshTjXb0x3jfizYVvvFS4LHJ0MEh8Cq67K7eqARGXxATGmf8snF4PEfo7fl1dz3gB/6rCfxMEgsRPw/UKbnea1webWYtPVJdV3JjoYJPZ0xOEKpP4EYvtuPJ3LpuoGiQMW3imr3joCixf2sgdBVDdI7O04tNNH1jHs872I01JiD0nJVNkgcW5V2b9sKxuN8aSO84LLpcoGiQ+CVl99Fxyd8eEwPiCWS1UNEseBcu7TvMM1ZgvjJPpSqapBfjGeIlhKrJUHE6dN/nblfdy5e1UNEiedr+Ug6Z1FOdACcWB2XPlQKlU0CBuhlhui5TZWVTTIbyT9arkxYt3yQ5J+XYlARYPEMZrlHvUHMujip22smi6TqhkkjME5s8sOzzBIGKVEqmYQVu0uPyxLrfKtZpA/Dk+QHy0/Rqx78KfhCfLjKgSqGeRfE9wmW0XrueKI23e/NVdjU7dTySBxD/l/pgZG/SkC36xyj3slg/xQ0ksp+cg0NYEbJP156kbmqL+SQeKmpN/NAY02thL4+Xgz19aMa89QySDsHFzPaCuz07CSQU5LitPIScsTiNPyTy3fjf17UMkgb0u6cn8k1NCBwF+GKyW+16GexauoZJB/cBj14uPpbAfisOtvr6Y3e3SkkkH+uwcHivYnUGJslQhi1BaD9B/k+9RYYmyVCAKD7DOOJytbYmyVCAKDTDbI96m4xNgqEQQG2WccT1a2xNgqEQQGmWyQ71NxibFVIohRRaZ59xnOfcsyzduXZ5fa+FDYBWOXSvhQ2AVj30pYatKX5z61sdRkH3oTlWWx4kRgG6plsWIDtKmLsNx9asL5+lnunmc1W042TM2GemtDbJjaimj+DGy5nZ/5phbZcrseLb7UEw5tWF4YDm1YXoONPeDYn+XF4dif5TXY2AMOjlteHA6OW16DjT3g6NHlxeHo0eU1OLEHHF69nEAcXr0c+3TLXH+QRtU9I9cfdEfav0Iu0OnPNFsjF+hkSS2cjyvY5heAK9jmZ97cIpd4NqNrLsglns3o5i/INdDzM+ca6PmZ79XiY5Lu3qsGCmcJPC7pnmzmQ8pXaUfhUe6XSXr3kMQ44L5eLum9A+7/xq5XNkgE/YykWysKt6KYnpV024r607Ur1Q0Sf9ne6UqMyo4SuKLyk7q6QUJMdhpOZ+oyOwc3IXIwSMyuvD9crnP+dOPEsuZPJV0i6ePK0TsYJPRjlW//UVxq1a7zE+Rs7C9Luq7/OLGs8RVJ1ztE7vIECS1jGXa8sJ/nIOyEMX4uKSY/YtV0+eRkkBAzPhzGB0RSO4H4IBgfBi2Sm0FC1BD3Lgt1+wf5pBs7R4PEsHld0lX9x0/pGt+QdHXpCI8JztUgF0l6jTsN08M9DqO+RlL8a5VcDRIis7EqP9TLbYTKhu5skGAU074x/UvaTCCmc2Na1zK5GyREv3G40ztOIyd9lcBNkl50BoNBzqjPk+SrLrB+cpzFgUG+GBjxTvIcL+7/fxG/RdJbzk8ODHK8+jG7FXtIXKeAYyo39nbYzVZt+mPAE+R4Mk9IutPsL2jEzBblI6JjkM0uiMES+x3OLW6Uz8bVzjbLR3bRE4OcTCsWOD5SeBVwTN/GzVwWCw93MQbvILvRiv0kDxbadBWbne4bd1vuRsIsN0+QvOCxM/H+YQfdvfkiq8wZPxsfqL4TsBd5DLI7ydgLEacIHtppKXH6yMOVD1jYXcrtJTDIdkabcsS5W/E0WfvMT7x8x1Oj5LlV7fLlSmKQHKeTcsUxp7dLumP40Hjp/tV1qSEOkn5K0tPDDNUnXWo0rQSD9BU+vsbfLOmUpLjtas4UJ9qflvQ8X8H7Yccg/VgerSkMcu34VT6Wi1/Yuam4TfbNoY34+v2qpDAIqTMBDNIZ6AnVxT3u8d4Sxrl4XPN1wTDVGj/RYonLcSmWfMRPpI/G5R8fjEaI94kP5+u6b0sYxFd7Ik8QwCAJSGTxJYBBfLUn8gQBDJKARBZfAhjEV3siTxDAIAlIZPElgEF8tSfyBAEMkoBEFl8CGMRXeyJPEMAgCUhk8SWAQXy1J/IEAQySgEQWXwIYxFd7Ik8QwCAJSGTxJYBBfLUn8gQBDJKARBZfAhjEV3siTxDAIAlIZPElgEF8tSfyBAEMkoBEFl8CGMRXeyJPEMAgCUhk8SWAQXy1J/IEAQySgEQWXwIYxFd7Ik8QwCAJSGTxJYBBfLUn8gQBDJKARBZfAhjEV3siTxDAIAlIZPElgEF8tSfyBAEMkoBEFl8CGMRXeyJPEMAgCUhk8SWAQXy1J/IEAQySgEQWXwIYxFd7Ik8QwCAJSGTxJYBBfLUn8gQBDJKARBZfAhjEV3siTxDAIAlIZPElgEF8tSfyBAEMkoBEFl8CGMRXeyJPEMAgCUhk8SWAQXy1J/IEAQySgEQWXwIYxFd7Ik8QwCAJSGTxJfA/4CryyUJWKzwAAAAASUVORK5CYII=',
|
||||||
|
input:
|
||||||
|
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAA5klEQVRYR+2VPwrCMBSHfwlFvIizq6u7y0vR2Qt4A0dP4AmcLSUUhI6Ozs5epA5NpKBQ1Ni0tAThZUxe8r735Z9A4CYC5wcDsAGngTiOJ8aYRR+HVEp5StP09m0tJwARLQEc+wAAsNJaJ38NsDXGnOsVSCnnAHbPvqbxTgam1tp1lUAIcdBaX+sAb1v0kYCIfs5/rdX5GjYB+J4dBmADbIANsIHWBpRSs7IspeszyrLsAsAO9hQT0R3AyJWgKIpxnudVjFdrbSA4gFJqY62NXOVFUbRPkqT0Kr/66n0Dh4pjADYQ3MADakKSIQVRq+oAAAAASUVORK5CYII='
|
||||||
|
}
|
||||||
|
export default cursorCollection
|
@ -6,7 +6,7 @@
|
|||||||
placement="bottom"
|
placement="bottom"
|
||||||
:width="80"
|
:width="80"
|
||||||
trigger="click"
|
trigger="click"
|
||||||
v-if="item.id === 5"
|
v-if="item.id === 5 || item.id === 6"
|
||||||
:disabled="currentItemIndex === -1"
|
:disabled="currentItemIndex === -1"
|
||||||
>
|
>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
@ -25,7 +25,8 @@
|
|||||||
<div class="name"> {{ item.name }} </div>
|
<div class="name"> {{ item.name }} </div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-form :model="state.moveForm">
|
<!-- 位置 -->
|
||||||
|
<el-form :model="state.moveForm" v-if="item.id === 5">
|
||||||
<el-form-item label="X">
|
<el-form-item label="X">
|
||||||
<el-input v-model="state.moveForm.x" placeholder="请输入" />
|
<el-input v-model="state.moveForm.x" placeholder="请输入" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -36,9 +37,28 @@
|
|||||||
<el-button size="small" color="#00329F" @click="moveFormSubmit">确认</el-button>
|
<el-button size="small" color="#00329F" @click="moveFormSubmit">确认</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
<!-- 旋转 -->
|
||||||
|
<el-form :model="state.rotationForm" v-if="item.id === 6">
|
||||||
|
<el-form-item label="角度">
|
||||||
|
<el-input v-model="state.rotationForm.angle" placeholder="请输入" />
|
||||||
|
</el-form-item>
|
||||||
|
<div style="text-align: right">
|
||||||
|
<el-button size="small" color="#00329F" @click="rotationFormSubmit">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
<!-- 字体 -->
|
||||||
|
<el-form :model="state.rotationForm" v-if="item.id === 13">
|
||||||
|
<el-form-item label="角度">
|
||||||
|
<el-input v-model="state.rotationForm.angle" placeholder="请输入" />
|
||||||
|
</el-form-item>
|
||||||
|
<div style="text-align: right">
|
||||||
|
<el-button size="small" color="#00329F" @click="rotationFormSubmit">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="item.id !== 5"
|
v-else
|
||||||
class="tool-item"
|
class="tool-item"
|
||||||
:class="
|
:class="
|
||||||
toolbarTypeIndex === item.id ? 'tool-active' : item.isActive ? 'right-tool-active' : ''
|
toolbarTypeIndex === item.id ? 'tool-active' : item.isActive ? 'right-tool-active' : ''
|
||||||
@ -48,10 +68,10 @@
|
|||||||
<Icon :icon="item.icon" :size="24" />
|
<Icon :icon="item.icon" :size="24" />
|
||||||
<div class="name"> {{ item.name }} </div>
|
<div class="name"> {{ item.name }} </div>
|
||||||
</div>
|
</div>
|
||||||
<div class="line" v-if="item.id === 3 || item.id === 10 || item.id === 19"></div>
|
<div class="line" v-if="item.id === 3 || item.id === 10 || item.id === 17"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right-tool-list">
|
<div class="right-tool-list" v-if="state.isShowToolbar">
|
||||||
<div
|
<div
|
||||||
v-for="item in state.rightToolList"
|
v-for="item in state.rightToolList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@ -66,10 +86,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="map-box" ref="imgWrap" @mousewheel.prevent="rollImg" style="overflow: hidden">
|
<div
|
||||||
|
class="map-box"
|
||||||
|
ref="imgWrap"
|
||||||
|
@mousewheel.prevent="rollImg"
|
||||||
|
style="overflow: hidden"
|
||||||
|
:style="{ cursor: state.cursorStyle }"
|
||||||
|
>
|
||||||
<div class="map-box-inner" ref="image" @mousedown.prevent="moveImg">
|
<div class="map-box-inner" ref="image" @mousedown.prevent="moveImg">
|
||||||
<img :src="imgBgObj.imgUrl" class="map-box-img" id="mapBg" />
|
<img :src="imgBgObj.imgUrl" class="map-box-img" id="mapBg" />
|
||||||
<div class="map-box-inner-dot" @click="mapClick" :class="state.isShowGrid ? 'grid-show' : ''">
|
<div
|
||||||
|
class="map-box-inner-dot"
|
||||||
|
@click="mapClick"
|
||||||
|
:class="state.isShowGrid ? 'grid-show' : ''"
|
||||||
|
v-if="test"
|
||||||
|
>
|
||||||
<VueDragResizeRotate
|
<VueDragResizeRotate
|
||||||
v-for="(item, index) in allHistoryList[currentIndex]"
|
v-for="(item, index) in allHistoryList[currentIndex]"
|
||||||
:key="index"
|
:key="index"
|
||||||
@ -87,9 +118,16 @@
|
|||||||
:draggable="item.draggable"
|
:draggable="item.draggable"
|
||||||
:resizable="item.resizable"
|
:resizable="item.resizable"
|
||||||
:rotatable="item.rotatable"
|
:rotatable="item.rotatable"
|
||||||
:lockAspectRatio="item.lockAspectRatio"
|
:lock-aspect-ratio="item.lockAspectRatio"
|
||||||
|
:handles="['tl', 'tr', 'bl', 'br', 'rot']"
|
||||||
|
style="border: none"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="sdiv"
|
||||||
|
:style="
|
||||||
|
currentItemIndex === index ? 'border: 1px dashed #000;box-sizing: border-box;' : ''
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="sdiv">
|
|
||||||
<img
|
<img
|
||||||
v-if="item.labelType === 'icon'"
|
v-if="item.labelType === 'icon'"
|
||||||
:src="item.img"
|
:src="item.img"
|
||||||
@ -106,21 +144,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 节点编辑 -->
|
||||||
<editNodeProperties
|
<editNodeProperties
|
||||||
ref="editNodePropertiesRef"
|
ref="editNodePropertiesRef"
|
||||||
:positionMapId="imgBgObj.positionMapId"
|
:positionMapId="imgBgObj.positionMapId"
|
||||||
@submitNodeSuccess="submitNodeSuccess"
|
@submitNodeSuccess="submitNodeSuccess"
|
||||||
/>
|
/>
|
||||||
|
<!-- 文字输入弹窗 -->
|
||||||
|
<textFormToolDialog ref="textFormToolDialogRef" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, defineComponent, reactive, nextTick, onMounted } from 'vue'
|
import { ref, defineComponent, reactive, nextTick, onMounted } from 'vue'
|
||||||
import editNodeProperties from './components/editNodeProperties.vue'
|
import editNodeProperties from './components-tool/editNodeProperties.vue'
|
||||||
|
import textFormToolDialog from './components-tool/textFormToolDialog.vue'
|
||||||
import * as MapApi from '@/api/map/map'
|
import * as MapApi from '@/api/map/map'
|
||||||
|
import cursorCollection from './cursorCollection'
|
||||||
|
|
||||||
defineOptions({ name: 'editMapPageRealTimeMap' })
|
defineOptions({ name: 'editMapPageRealTimeMap' })
|
||||||
|
|
||||||
|
const textFormToolDialogRef = ref() //文字输入弹窗
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const formLoading = ref(false)
|
const formLoading = ref(false)
|
||||||
|
|
||||||
@ -133,8 +177,8 @@ const imgBgObj = reactive({
|
|||||||
}) //地图背景
|
}) //地图背景
|
||||||
const imgList = ref([]) //所有的图标的列表
|
const imgList = ref([]) //所有的图标的列表
|
||||||
|
|
||||||
const list = ref([])
|
|
||||||
//获取地图点位
|
//获取地图点位
|
||||||
|
const list = ref([])
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
let data = await MapApi.getPositionMapGetMap()
|
let data = await MapApi.getPositionMapGetMap()
|
||||||
let mapList = []
|
let mapList = []
|
||||||
@ -165,13 +209,18 @@ const getMapData = async (item) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 缩放停止
|
// 缩放停止
|
||||||
|
const test = ref(true)
|
||||||
|
|
||||||
const resizeEnd = (x, y, w, h, item, index) => {
|
const resizeEnd = (x, y, w, h, item, index) => {
|
||||||
console.log('缩放')
|
test.value = false
|
||||||
|
console.log('缩放', w, h)
|
||||||
|
nextTick(() => {
|
||||||
imgList.value[index].x = x
|
imgList.value[index].x = x
|
||||||
imgList.value[index].y = y
|
imgList.value[index].y = y
|
||||||
imgList.value[index].w = w
|
imgList.value[index].w = w
|
||||||
imgList.value[index].h = h
|
imgList.value[index].h = h
|
||||||
addEditHistory()
|
addEditHistory()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// 拖拽停止
|
// 拖拽停止
|
||||||
const dragEnd = (x, y, item, index) => {
|
const dragEnd = (x, y, item, index) => {
|
||||||
@ -191,10 +240,10 @@ const rotateEnd = (angle, item, index) => {
|
|||||||
//选中
|
//选中
|
||||||
const editNodePropertiesRef = ref()
|
const editNodePropertiesRef = ref()
|
||||||
const activatedHandle = (item, index) => {
|
const activatedHandle = (item, index) => {
|
||||||
console.log('选中', item)
|
// console.log('选中', item, index)
|
||||||
currentItemIndex.value = index
|
currentItemIndex.value = index
|
||||||
if (item.labelType === 'node') {
|
if (item.labelType === 'node') {
|
||||||
if (toolbarTypeIndex.value === 25) {
|
if (toolbarTypeIndex.value === 23) {
|
||||||
editNodePropertiesRef.value.open(item)
|
editNodePropertiesRef.value.open(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,9 +261,15 @@ const addEditHistory = () => {
|
|||||||
currentIndex.value = allHistoryList.value.length
|
currentIndex.value = allHistoryList.value.length
|
||||||
allHistoryList.value.push(JSON.parse(JSON.stringify(imgList.value)))
|
allHistoryList.value.push(JSON.parse(JSON.stringify(imgList.value)))
|
||||||
} else {
|
} else {
|
||||||
currentIndex.value++
|
|
||||||
allHistoryList.value.push(JSON.parse(JSON.stringify(imgList.value)))
|
allHistoryList.value.push(JSON.parse(JSON.stringify(imgList.value)))
|
||||||
|
currentIndex.value++
|
||||||
|
console.log(currentIndex.value)
|
||||||
|
console.log(
|
||||||
|
allHistoryList.value[currentIndex.value][currentItemIndex.value],
|
||||||
|
allHistoryList.value[currentIndex.value][currentItemIndex.value]
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
test.value = true
|
||||||
console.log(allHistoryList.value, 'allHistoryList')
|
console.log(allHistoryList.value, 'allHistoryList')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +296,7 @@ const backNextStep = () => {
|
|||||||
|
|
||||||
//地图点击
|
//地图点击
|
||||||
const mapClick = (e) => {
|
const mapClick = (e) => {
|
||||||
if (toolbarTypeIndex.value === 24) {
|
if (toolbarTypeIndex.value === 22) {
|
||||||
//绘制节点
|
//绘制节点
|
||||||
imgList.value.push({
|
imgList.value.push({
|
||||||
x: e.offsetX,
|
x: e.offsetX,
|
||||||
@ -252,6 +307,7 @@ const mapClick = (e) => {
|
|||||||
draggable: false,
|
draggable: false,
|
||||||
resizable: false,
|
resizable: false,
|
||||||
rotatable: false,
|
rotatable: false,
|
||||||
|
lockAspectRatio: false, //横纵比
|
||||||
img: '',
|
img: '',
|
||||||
labelType: 'node'
|
labelType: 'node'
|
||||||
})
|
})
|
||||||
@ -379,60 +435,48 @@ const state = reactive({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 14,
|
id: 14,
|
||||||
name: '设备',
|
|
||||||
icon: 'ep:folder-add',
|
|
||||||
isActive: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 15,
|
|
||||||
name: '车辆',
|
|
||||||
icon: 'ep:folder-add',
|
|
||||||
isActive: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 16,
|
|
||||||
name: '测距',
|
name: '测距',
|
||||||
icon: 'ep:folder-add',
|
icon: 'ep:folder-add',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 17,
|
id: 15,
|
||||||
name: '图层',
|
name: '图层',
|
||||||
icon: 'ep:folder-add',
|
icon: 'ep:folder-add',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 18,
|
id: 16,
|
||||||
name: '标记',
|
name: '标记',
|
||||||
icon: 'ep:folder-add',
|
icon: 'ep:folder-add',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 19,
|
id: 17,
|
||||||
name: '网格',
|
name: '网格',
|
||||||
icon: 'ep:folder-add',
|
icon: 'ep:folder-add',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 20,
|
id: 18,
|
||||||
name: '放大',
|
name: '放大',
|
||||||
icon: 'ep:zoom-in',
|
icon: 'ep:zoom-in',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 21,
|
id: 19,
|
||||||
name: '缩小',
|
name: '缩小',
|
||||||
icon: 'ep:zoom-out',
|
icon: 'ep:zoom-out',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 22,
|
id: 20,
|
||||||
name: '撤回',
|
name: '撤回',
|
||||||
icon: 'ep:top-left',
|
icon: 'ep:top-left',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 23,
|
id: 21,
|
||||||
name: '重做',
|
name: '重做',
|
||||||
icon: 'ep:top-right',
|
icon: 'ep:top-right',
|
||||||
isActive: false
|
isActive: false
|
||||||
@ -440,48 +484,59 @@ const state = reactive({
|
|||||||
],
|
],
|
||||||
rightToolList: [
|
rightToolList: [
|
||||||
{
|
{
|
||||||
id: 24,
|
id: 22,
|
||||||
name: '绘制节点',
|
name: '绘制节点',
|
||||||
icon: 'ep:circle-plus-filled',
|
icon: 'ep:circle-plus-filled',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 25,
|
id: 23,
|
||||||
name: '编辑节点',
|
name: '编辑节点',
|
||||||
icon: 'ep:circle-plus-filled',
|
icon: 'ep:circle-plus-filled',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 26,
|
id: 24,
|
||||||
name: '绘制路线',
|
name: '绘制路线',
|
||||||
icon: 'ep:semi-select',
|
icon: 'ep:semi-select',
|
||||||
isActive: false
|
isActive: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 27,
|
id: 25,
|
||||||
name: '编辑路线',
|
name: '编辑路线',
|
||||||
icon: 'ep:semi-select',
|
icon: 'ep:semi-select',
|
||||||
isActive: false
|
isActive: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
isShowGrid: false,
|
isShowToolbar: false, //工具栏展示隐藏
|
||||||
|
isShowGrid: false, //网格展示隐藏
|
||||||
moveForm: {
|
moveForm: {
|
||||||
x: '',
|
x: '',
|
||||||
y: ''
|
y: ''
|
||||||
}
|
}, //移动的表单
|
||||||
|
rotationForm: {
|
||||||
|
angle: ''
|
||||||
|
}, //旋转的表单
|
||||||
|
copyMapItem: '', //复制的值
|
||||||
|
cursorStyle: 'auto'
|
||||||
})
|
})
|
||||||
const toolbarClick = (item) => {
|
const toolbarClick = (item) => {
|
||||||
let type = item.id
|
let type = item.id
|
||||||
if (currentItemIndex.value === -1 && type === 5) {
|
if (currentItemIndex.value === -1 && (type === 5 || type === 6 || type === 7 || type === 9)) {
|
||||||
message.warning('请先选择要操作的图标')
|
message.warning('请先选择要操作的对象')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (type === 8 && !state.copyMapItem) {
|
||||||
|
message.warning('请先复制对象')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toolbarTypeIndex.value === type) {
|
if ((type === 10 || type === 13 || type === 17) && toolbarTypeIndex.value === type) {
|
||||||
toolbarTypeIndex.value = 0
|
toolbarTypeIndex.value = 0
|
||||||
} else {
|
} else {
|
||||||
toolbarTypeIndex.value = type
|
toolbarTypeIndex.value = type
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 1:
|
case 1:
|
||||||
break
|
break
|
||||||
@ -497,18 +552,43 @@ const toolbarClick = (item) => {
|
|||||||
case 6:
|
case 6:
|
||||||
break
|
break
|
||||||
case 7:
|
case 7:
|
||||||
|
//复制
|
||||||
|
state.copyMapItem = allHistoryList.value[currentIndex.value][currentItemIndex.value]
|
||||||
break
|
break
|
||||||
case 8:
|
case 8:
|
||||||
|
//粘贴
|
||||||
|
let item = JSON.parse(JSON.stringify(state.copyMapItem))
|
||||||
|
item.x = item.x + 50
|
||||||
|
item.y = item.y + 50
|
||||||
|
imgList.value.push(item)
|
||||||
|
addEditHistory()
|
||||||
break
|
break
|
||||||
case 9:
|
case 9:
|
||||||
|
//删除
|
||||||
|
imgList.value.splice(currentItemIndex.value, 1)
|
||||||
|
addEditHistory()
|
||||||
break
|
break
|
||||||
case 10:
|
case 10:
|
||||||
|
//工具
|
||||||
|
if (toolbarTypeIndex.value === 10) {
|
||||||
|
state.isShowToolbar = true
|
||||||
|
} else {
|
||||||
|
state.isShowToolbar = false
|
||||||
|
}
|
||||||
break
|
break
|
||||||
case 11:
|
case 11:
|
||||||
break
|
break
|
||||||
case 12:
|
case 12:
|
||||||
break
|
break
|
||||||
case 13:
|
case 13:
|
||||||
|
//文字
|
||||||
|
textFormToolDialogRef.value.open()
|
||||||
|
|
||||||
|
// if (toolbarTypeIndex.value === 13) {
|
||||||
|
// state.cursorStyle = `url('${cursorCollection.input}'),auto`
|
||||||
|
// } else {
|
||||||
|
// state.cursorStyle = `auto`
|
||||||
|
// }
|
||||||
break
|
break
|
||||||
case 14:
|
case 14:
|
||||||
break
|
break
|
||||||
@ -517,12 +597,8 @@ const toolbarClick = (item) => {
|
|||||||
case 16:
|
case 16:
|
||||||
break
|
break
|
||||||
case 17:
|
case 17:
|
||||||
break
|
|
||||||
case 18:
|
|
||||||
break
|
|
||||||
case 19:
|
|
||||||
//网格
|
//网格
|
||||||
if (toolbarTypeIndex.value === 19) {
|
if (toolbarTypeIndex.value === 17) {
|
||||||
state.isShowGrid = true
|
state.isShowGrid = true
|
||||||
item.isActive = true
|
item.isActive = true
|
||||||
} else {
|
} else {
|
||||||
@ -530,29 +606,27 @@ const toolbarClick = (item) => {
|
|||||||
item.isActive = false
|
item.isActive = false
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case 18:
|
||||||
|
break
|
||||||
|
case 19:
|
||||||
|
break
|
||||||
case 20:
|
case 20:
|
||||||
break
|
|
||||||
case 21:
|
|
||||||
break
|
|
||||||
case 22:
|
|
||||||
//上一步
|
//上一步
|
||||||
backPreviousStep()
|
backPreviousStep()
|
||||||
break
|
break
|
||||||
case 23:
|
case 21:
|
||||||
//下一步
|
//下一步
|
||||||
backNextStep()
|
backNextStep()
|
||||||
break
|
break
|
||||||
case 24:
|
case 22:
|
||||||
drawNodes()
|
drawNodes()
|
||||||
break
|
break
|
||||||
|
case 23:
|
||||||
|
break
|
||||||
|
case 24:
|
||||||
|
break
|
||||||
case 25:
|
case 25:
|
||||||
break
|
break
|
||||||
case 26:
|
|
||||||
break
|
|
||||||
case 27:
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,6 +635,10 @@ const moveFormSubmit = () => {
|
|||||||
allHistoryList.value[currentIndex.value][currentItemIndex.value].x = state.moveForm.x
|
allHistoryList.value[currentIndex.value][currentItemIndex.value].x = state.moveForm.x
|
||||||
allHistoryList.value[currentIndex.value][currentItemIndex.value].y = state.moveForm.y
|
allHistoryList.value[currentIndex.value][currentItemIndex.value].y = state.moveForm.y
|
||||||
}
|
}
|
||||||
|
//旋转工具表单提交
|
||||||
|
const rotationFormSubmit = () => {
|
||||||
|
allHistoryList.value[currentIndex.value][currentItemIndex.value].angle = state.rotationForm.angle
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
imgList.value = [
|
imgList.value = [
|
||||||
@ -573,6 +651,7 @@ onMounted(() => {
|
|||||||
draggable: true,
|
draggable: true,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
rotatable: true,
|
rotatable: true,
|
||||||
|
lockAspectRatio: true, //横纵比
|
||||||
img: 'https://sys.znkjfw.com/imgs/process/%E8%AF%B7%E5%81%87.png',
|
img: 'https://sys.znkjfw.com/imgs/process/%E8%AF%B7%E5%81%87.png',
|
||||||
labelType: 'icon'
|
labelType: 'icon'
|
||||||
},
|
},
|
||||||
@ -585,6 +664,7 @@ onMounted(() => {
|
|||||||
draggable: true,
|
draggable: true,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
rotatable: true,
|
rotatable: true,
|
||||||
|
lockAspectRatio: false, //横纵比
|
||||||
img: 'https://sys.znkjfw.com/imgs/process/%E8%AF%B7%E5%81%87.png',
|
img: 'https://sys.znkjfw.com/imgs/process/%E8%AF%B7%E5%81%87.png',
|
||||||
labelType: 'icon'
|
labelType: 'icon'
|
||||||
}
|
}
|
||||||
@ -619,8 +699,8 @@ onMounted(() => {
|
|||||||
background: linear-gradient(-90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px),
|
background: linear-gradient(-90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px),
|
||||||
linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px);
|
linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px);
|
||||||
background-size:
|
background-size:
|
||||||
20px 20px,
|
10px 10px,
|
||||||
20px 20px;
|
10px 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -628,6 +708,7 @@ onMounted(() => {
|
|||||||
.sdiv {
|
.sdiv {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-tool-list {
|
.top-tool-list {
|
||||||
@ -649,6 +730,8 @@ onMounted(() => {
|
|||||||
|
|
||||||
.tool-item {
|
.tool-item {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
// cursor: url('https://api.znkjfw.com/admin-api/infra/file/4/get/输入_png_179_1738982726561.png'),
|
||||||
|
// auto;
|
||||||
width: 52px;
|
width: 52px;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
93
src/views/mapPage/realTimeMap/test.vue
Normal file
93
src/views/mapPage/realTimeMap/test.vue
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
@mousedown="startSelection"
|
||||||
|
@mousemove="updateSelection"
|
||||||
|
@mouseup="endSelection"
|
||||||
|
style="position: relative; width: 100%; height: 900px"
|
||||||
|
>
|
||||||
|
<!-- 绘制框选区域 -->
|
||||||
|
<div
|
||||||
|
v-if="isSelecting"
|
||||||
|
:style="{
|
||||||
|
position: 'absolute',
|
||||||
|
left: `${selectionBox.x}px`,
|
||||||
|
top: `${selectionBox.y}px`,
|
||||||
|
width: `${selectionBox.width}px`,
|
||||||
|
height: `${selectionBox.height}px`,
|
||||||
|
border: '1px solid blue',
|
||||||
|
backgroundColor: 'rgba(0, 0, 255, 0.1)'
|
||||||
|
}"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<!-- 绘制点位 -->
|
||||||
|
<div
|
||||||
|
v-for="(point, index) in points"
|
||||||
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
position: 'absolute',
|
||||||
|
left: `${point.x}px`,
|
||||||
|
top: `${point.y}px`,
|
||||||
|
width: '100px',
|
||||||
|
height: '100px',
|
||||||
|
backgroundColor: selectedPoints.includes(point) ? 'red' : '#fff'
|
||||||
|
}"
|
||||||
|
>设备{{ index }}</div
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
const points = ref([
|
||||||
|
{ x: 210, y: 210 },
|
||||||
|
{ x: 330, y: 500 },
|
||||||
|
{ x: 840, y: 440 },
|
||||||
|
{ x: 230, y: 400 },
|
||||||
|
{ x: 750, y: 640 }
|
||||||
|
])
|
||||||
|
|
||||||
|
const isSelecting = ref(false)
|
||||||
|
const selectionBox = ref({ x: 0, y: 0, width: 0, height: 0 })
|
||||||
|
const startPos = ref({ x: 0, y: 0 })
|
||||||
|
const selectedPoints = ref([])
|
||||||
|
|
||||||
|
const startSelection = (event) => {
|
||||||
|
isSelecting.value = true
|
||||||
|
startPos.value = { x: event.offsetX, y: event.offsetY }
|
||||||
|
selectionBox.value = { x: event.offsetX, y: event.offsetY, width: 0, height: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateSelection = (event) => {
|
||||||
|
if (isSelecting.value) {
|
||||||
|
selectionBox.value.width = event.offsetX - startPos.value.x
|
||||||
|
selectionBox.value.height = event.offsetY - startPos.value.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const endSelection = () => {
|
||||||
|
isSelecting.value = false
|
||||||
|
selectedPoints.value = points.value.filter((point) => {
|
||||||
|
return (
|
||||||
|
point.x >= Math.min(startPos.value.x, startPos.value.x + selectionBox.value.width) &&
|
||||||
|
point.x <= Math.max(startPos.value.x, startPos.value.x + selectionBox.value.width) &&
|
||||||
|
point.y >= Math.min(startPos.value.y, startPos.value.y + selectionBox.value.height) &&
|
||||||
|
point.y <= Math.max(startPos.value.y, startPos.value.y + selectionBox.value.height)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
points,
|
||||||
|
isSelecting,
|
||||||
|
selectionBox,
|
||||||
|
selectedPoints,
|
||||||
|
startSelection,
|
||||||
|
updateSelection,
|
||||||
|
endSelection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user