鼠标地图多选框选、地图工具复制、地图工具粘贴、地图工具删除、地图工具文字输入
This commit is contained in:
parent
9d0cc0b096
commit
325de2cc64
@ -90,6 +90,18 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
||||
icon: 'ep:edit',
|
||||
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>
|
||||
<el-dialog v-model="dialogFormVisible" title="节点属性" width="540">
|
||||
<el-form :model="form" label-width="75">
|
||||
<Dialog v-model="dialogFormVisible" title="节点属性" width="540" class="node-form-dialog">
|
||||
<el-form :model="form" label-width="auto">
|
||||
<el-form-item label="X" prop="locationX" required>
|
||||
<el-input v-model="form.locationX" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
@ -99,7 +99,7 @@
|
||||
<el-button type="primary" @click="submit"> 确认 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -212,3 +212,15 @@ const deviceTypeChange = () => {
|
||||
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
</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"
|
||||
:width="80"
|
||||
trigger="click"
|
||||
v-if="item.id === 5"
|
||||
v-if="item.id === 5 || item.id === 6"
|
||||
:disabled="currentItemIndex === -1"
|
||||
>
|
||||
<template #reference>
|
||||
@ -25,7 +25,8 @@
|
||||
<div class="name"> {{ item.name }} </div>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="state.moveForm">
|
||||
<!-- 位置 -->
|
||||
<el-form :model="state.moveForm" v-if="item.id === 5">
|
||||
<el-form-item label="X">
|
||||
<el-input v-model="state.moveForm.x" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
@ -36,9 +37,28 @@
|
||||
<el-button size="small" color="#00329F" @click="moveFormSubmit">确认</el-button>
|
||||
</div>
|
||||
</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>
|
||||
|
||||
<div
|
||||
v-if="item.id !== 5"
|
||||
v-else
|
||||
class="tool-item"
|
||||
:class="
|
||||
toolbarTypeIndex === item.id ? 'tool-active' : item.isActive ? 'right-tool-active' : ''
|
||||
@ -48,10 +68,10 @@
|
||||
<Icon :icon="item.icon" :size="24" />
|
||||
<div class="name"> {{ item.name }} </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 class="right-tool-list">
|
||||
<div class="right-tool-list" v-if="state.isShowToolbar">
|
||||
<div
|
||||
v-for="item in state.rightToolList"
|
||||
:key="item.id"
|
||||
@ -66,10 +86,21 @@
|
||||
</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">
|
||||
<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
|
||||
v-for="(item, index) in allHistoryList[currentIndex]"
|
||||
:key="index"
|
||||
@ -87,9 +118,16 @@
|
||||
:draggable="item.draggable"
|
||||
:resizable="item.resizable"
|
||||
: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
|
||||
v-if="item.labelType === 'icon'"
|
||||
:src="item.img"
|
||||
@ -106,21 +144,27 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 节点编辑 -->
|
||||
<editNodeProperties
|
||||
ref="editNodePropertiesRef"
|
||||
:positionMapId="imgBgObj.positionMapId"
|
||||
@submitNodeSuccess="submitNodeSuccess"
|
||||
/>
|
||||
<!-- 文字输入弹窗 -->
|
||||
<textFormToolDialog ref="textFormToolDialogRef" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
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 cursorCollection from './cursorCollection'
|
||||
|
||||
defineOptions({ name: 'editMapPageRealTimeMap' })
|
||||
|
||||
const textFormToolDialogRef = ref() //文字输入弹窗
|
||||
|
||||
const message = useMessage() // 消息弹窗
|
||||
const formLoading = ref(false)
|
||||
|
||||
@ -133,8 +177,8 @@ const imgBgObj = reactive({
|
||||
}) //地图背景
|
||||
const imgList = ref([]) //所有的图标的列表
|
||||
|
||||
const list = ref([])
|
||||
//获取地图点位
|
||||
const list = ref([])
|
||||
const getList = async () => {
|
||||
let data = await MapApi.getPositionMapGetMap()
|
||||
let mapList = []
|
||||
@ -165,13 +209,18 @@ const getMapData = async (item) => {
|
||||
}
|
||||
|
||||
// 缩放停止
|
||||
const test = ref(true)
|
||||
|
||||
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].y = y
|
||||
imgList.value[index].w = w
|
||||
imgList.value[index].h = h
|
||||
addEditHistory()
|
||||
})
|
||||
}
|
||||
// 拖拽停止
|
||||
const dragEnd = (x, y, item, index) => {
|
||||
@ -191,10 +240,10 @@ const rotateEnd = (angle, item, index) => {
|
||||
//选中
|
||||
const editNodePropertiesRef = ref()
|
||||
const activatedHandle = (item, index) => {
|
||||
console.log('选中', item)
|
||||
// console.log('选中', item, index)
|
||||
currentItemIndex.value = index
|
||||
if (item.labelType === 'node') {
|
||||
if (toolbarTypeIndex.value === 25) {
|
||||
if (toolbarTypeIndex.value === 23) {
|
||||
editNodePropertiesRef.value.open(item)
|
||||
}
|
||||
}
|
||||
@ -212,9 +261,15 @@ const addEditHistory = () => {
|
||||
currentIndex.value = allHistoryList.value.length
|
||||
allHistoryList.value.push(JSON.parse(JSON.stringify(imgList.value)))
|
||||
} else {
|
||||
currentIndex.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')
|
||||
}
|
||||
|
||||
@ -241,7 +296,7 @@ const backNextStep = () => {
|
||||
|
||||
//地图点击
|
||||
const mapClick = (e) => {
|
||||
if (toolbarTypeIndex.value === 24) {
|
||||
if (toolbarTypeIndex.value === 22) {
|
||||
//绘制节点
|
||||
imgList.value.push({
|
||||
x: e.offsetX,
|
||||
@ -252,6 +307,7 @@ const mapClick = (e) => {
|
||||
draggable: false,
|
||||
resizable: false,
|
||||
rotatable: false,
|
||||
lockAspectRatio: false, //横纵比
|
||||
img: '',
|
||||
labelType: 'node'
|
||||
})
|
||||
@ -379,60 +435,48 @@ const state = reactive({
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
name: '设备',
|
||||
icon: 'ep:folder-add',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
name: '车辆',
|
||||
icon: 'ep:folder-add',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 16,
|
||||
name: '测距',
|
||||
icon: 'ep:folder-add',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 17,
|
||||
id: 15,
|
||||
name: '图层',
|
||||
icon: 'ep:folder-add',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 18,
|
||||
id: 16,
|
||||
name: '标记',
|
||||
icon: 'ep:folder-add',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 19,
|
||||
id: 17,
|
||||
name: '网格',
|
||||
icon: 'ep:folder-add',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 20,
|
||||
id: 18,
|
||||
name: '放大',
|
||||
icon: 'ep:zoom-in',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 21,
|
||||
id: 19,
|
||||
name: '缩小',
|
||||
icon: 'ep:zoom-out',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 22,
|
||||
id: 20,
|
||||
name: '撤回',
|
||||
icon: 'ep:top-left',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 23,
|
||||
id: 21,
|
||||
name: '重做',
|
||||
icon: 'ep:top-right',
|
||||
isActive: false
|
||||
@ -440,48 +484,59 @@ const state = reactive({
|
||||
],
|
||||
rightToolList: [
|
||||
{
|
||||
id: 24,
|
||||
id: 22,
|
||||
name: '绘制节点',
|
||||
icon: 'ep:circle-plus-filled',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 25,
|
||||
id: 23,
|
||||
name: '编辑节点',
|
||||
icon: 'ep:circle-plus-filled',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 26,
|
||||
id: 24,
|
||||
name: '绘制路线',
|
||||
icon: 'ep:semi-select',
|
||||
isActive: false
|
||||
},
|
||||
{
|
||||
id: 27,
|
||||
id: 25,
|
||||
name: '编辑路线',
|
||||
icon: 'ep:semi-select',
|
||||
isActive: false
|
||||
}
|
||||
],
|
||||
isShowGrid: false,
|
||||
isShowToolbar: false, //工具栏展示隐藏
|
||||
isShowGrid: false, //网格展示隐藏
|
||||
moveForm: {
|
||||
x: '',
|
||||
y: ''
|
||||
}
|
||||
}, //移动的表单
|
||||
rotationForm: {
|
||||
angle: ''
|
||||
}, //旋转的表单
|
||||
copyMapItem: '', //复制的值
|
||||
cursorStyle: 'auto'
|
||||
})
|
||||
const toolbarClick = (item) => {
|
||||
let type = item.id
|
||||
if (currentItemIndex.value === -1 && type === 5) {
|
||||
message.warning('请先选择要操作的图标')
|
||||
if (currentItemIndex.value === -1 && (type === 5 || type === 6 || type === 7 || type === 9)) {
|
||||
message.warning('请先选择要操作的对象')
|
||||
return
|
||||
}
|
||||
if (type === 8 && !state.copyMapItem) {
|
||||
message.warning('请先复制对象')
|
||||
return
|
||||
}
|
||||
|
||||
if (toolbarTypeIndex.value === type) {
|
||||
if ((type === 10 || type === 13 || type === 17) && toolbarTypeIndex.value === type) {
|
||||
toolbarTypeIndex.value = 0
|
||||
} else {
|
||||
toolbarTypeIndex.value = type
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
break
|
||||
@ -497,18 +552,43 @@ const toolbarClick = (item) => {
|
||||
case 6:
|
||||
break
|
||||
case 7:
|
||||
//复制
|
||||
state.copyMapItem = allHistoryList.value[currentIndex.value][currentItemIndex.value]
|
||||
break
|
||||
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
|
||||
case 9:
|
||||
//删除
|
||||
imgList.value.splice(currentItemIndex.value, 1)
|
||||
addEditHistory()
|
||||
break
|
||||
case 10:
|
||||
//工具
|
||||
if (toolbarTypeIndex.value === 10) {
|
||||
state.isShowToolbar = true
|
||||
} else {
|
||||
state.isShowToolbar = false
|
||||
}
|
||||
break
|
||||
case 11:
|
||||
break
|
||||
case 12:
|
||||
break
|
||||
case 13:
|
||||
//文字
|
||||
textFormToolDialogRef.value.open()
|
||||
|
||||
// if (toolbarTypeIndex.value === 13) {
|
||||
// state.cursorStyle = `url('${cursorCollection.input}'),auto`
|
||||
// } else {
|
||||
// state.cursorStyle = `auto`
|
||||
// }
|
||||
break
|
||||
case 14:
|
||||
break
|
||||
@ -517,12 +597,8 @@ const toolbarClick = (item) => {
|
||||
case 16:
|
||||
break
|
||||
case 17:
|
||||
break
|
||||
case 18:
|
||||
break
|
||||
case 19:
|
||||
//网格
|
||||
if (toolbarTypeIndex.value === 19) {
|
||||
if (toolbarTypeIndex.value === 17) {
|
||||
state.isShowGrid = true
|
||||
item.isActive = true
|
||||
} else {
|
||||
@ -530,29 +606,27 @@ const toolbarClick = (item) => {
|
||||
item.isActive = false
|
||||
}
|
||||
break
|
||||
case 18:
|
||||
break
|
||||
case 19:
|
||||
break
|
||||
case 20:
|
||||
break
|
||||
case 21:
|
||||
break
|
||||
case 22:
|
||||
//上一步
|
||||
backPreviousStep()
|
||||
break
|
||||
case 23:
|
||||
case 21:
|
||||
//下一步
|
||||
backNextStep()
|
||||
break
|
||||
case 24:
|
||||
case 22:
|
||||
drawNodes()
|
||||
break
|
||||
case 23:
|
||||
break
|
||||
case 24:
|
||||
break
|
||||
case 25:
|
||||
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].y = state.moveForm.y
|
||||
}
|
||||
//旋转工具表单提交
|
||||
const rotationFormSubmit = () => {
|
||||
allHistoryList.value[currentIndex.value][currentItemIndex.value].angle = state.rotationForm.angle
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
imgList.value = [
|
||||
@ -573,6 +651,7 @@ onMounted(() => {
|
||||
draggable: true,
|
||||
resizable: true,
|
||||
rotatable: true,
|
||||
lockAspectRatio: true, //横纵比
|
||||
img: 'https://sys.znkjfw.com/imgs/process/%E8%AF%B7%E5%81%87.png',
|
||||
labelType: 'icon'
|
||||
},
|
||||
@ -585,6 +664,7 @@ onMounted(() => {
|
||||
draggable: true,
|
||||
resizable: true,
|
||||
rotatable: true,
|
||||
lockAspectRatio: false, //横纵比
|
||||
img: 'https://sys.znkjfw.com/imgs/process/%E8%AF%B7%E5%81%87.png',
|
||||
labelType: 'icon'
|
||||
}
|
||||
@ -619,8 +699,8 @@ onMounted(() => {
|
||||
background: linear-gradient(-90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px),
|
||||
linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px);
|
||||
background-size:
|
||||
20px 20px,
|
||||
20px 20px;
|
||||
10px 10px,
|
||||
10px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -628,6 +708,7 @@ onMounted(() => {
|
||||
.sdiv {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.top-tool-list {
|
||||
@ -649,6 +730,8 @@ onMounted(() => {
|
||||
|
||||
.tool-item {
|
||||
cursor: pointer;
|
||||
// cursor: url('https://api.znkjfw.com/admin-api/infra/file/4/get/输入_png_179_1738982726561.png'),
|
||||
// auto;
|
||||
width: 52px;
|
||||
height: 70px;
|
||||
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