1、增加路线右击自定义菜单,按照开始点和结束点自动生成左上、右下、右上、左下直角拐角
2、点击地图显示实际位置改为点击到节点则按照节点的位置展示
This commit is contained in:
parent
8efb54dd52
commit
cd17472173
@ -497,6 +497,7 @@
|
||||
<!-- 节点合集 -->
|
||||
<div
|
||||
@mousedown="startFromPoint(index, $event)"
|
||||
@click.stop="handleNodeClick(item)"
|
||||
:style="{ width: item.locationWidePx + 'px', height: item.locationDeepPx + 'px' }"
|
||||
>
|
||||
<!-- 1 路径点 -->
|
||||
@ -700,6 +701,7 @@
|
||||
:stroke="curve.isSelected ? '#f48924' : '#2d72d9'"
|
||||
:stroke-width="state.routeWidthForm.routeWidth"
|
||||
@click="(e) => handleChooseRoute(curve, index, 'line', e)"
|
||||
@contextmenu="handleCurveContextMenu(curve, index, $event)"
|
||||
/>
|
||||
<text
|
||||
style="user-select: none"
|
||||
@ -724,6 +726,7 @@
|
||||
:stroke-width="state.routeWidthForm.routeWidth"
|
||||
fill="none"
|
||||
@click="handleChooseRoute(curve, index)"
|
||||
@contextmenu="handleCurveContextMenu(curve, index, $event)"
|
||||
/>
|
||||
<text
|
||||
style="user-select: none"
|
||||
@ -766,7 +769,12 @@
|
||||
</template>
|
||||
</template>
|
||||
<!-- 控制点circle统一渲染,保证层级最高 -->
|
||||
<template v-if="state.currentDragTarget.index !== null">
|
||||
<template
|
||||
v-if="
|
||||
state.currentDragTarget.index !== null &&
|
||||
state.mapRouteList[state.currentDragTarget.index].method !== 0
|
||||
"
|
||||
>
|
||||
<circle
|
||||
id="startCircle"
|
||||
:cx="state.mapRouteList[state.currentDragTarget.index].beginControlX"
|
||||
@ -958,7 +966,7 @@
|
||||
:imgBgObj="imgBgObj"
|
||||
@submit-batch-copying-form-success="submitBatchCopyingFormSuccess"
|
||||
/>
|
||||
|
||||
<!-- 节点右击菜单 -->
|
||||
<div
|
||||
v-if="state.contextMenu.visible"
|
||||
class="context-menu"
|
||||
@ -974,6 +982,24 @@
|
||||
>生成检测点</div
|
||||
>
|
||||
</div>
|
||||
<!-- 曲线右击菜单 -->
|
||||
<div
|
||||
v-if="state.curveContextMenu.visible"
|
||||
class="context-menu"
|
||||
:style="{ left: state.curveContextMenu.x + 'px', top: state.curveContextMenu.y + 'px' }"
|
||||
@click.stop
|
||||
>
|
||||
<div class="context-menu-item" @click="deleteCurveRoute">删除</div>
|
||||
<div class="context-menu-item" @click="contextMenuEditRoute">编辑路线</div>
|
||||
<template
|
||||
v-for="dir in getAvailableRightAngleDirections(state.curveContextMenu.currentCurve)"
|
||||
:key="dir"
|
||||
>
|
||||
<div class="context-menu-item" @click="() => setCurveRightAngle(dir)">
|
||||
{{ rightAngleDirectionLabel(dir) }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -1742,6 +1768,13 @@ const state = reactive({
|
||||
y: 0, // 菜单y坐标
|
||||
currentItem: null, // 当前右击的库位信息
|
||||
currentIndex: -1 // 当前右击的库位索引
|
||||
},
|
||||
curveContextMenu: {
|
||||
visible: false,
|
||||
x: 0,
|
||||
y: 0,
|
||||
currentCurve: null,
|
||||
currentIndex: -1
|
||||
}
|
||||
})
|
||||
|
||||
@ -2120,6 +2153,7 @@ const handleContextMenu = (item, index, event) => {
|
||||
state.contextMenu.y = event.clientY
|
||||
state.contextMenu.currentItem = item
|
||||
state.contextMenu.currentIndex = index
|
||||
state.currentItemIndex = index
|
||||
}
|
||||
|
||||
// 隐藏右击菜单
|
||||
@ -4347,6 +4381,129 @@ const findClosestPoint = (x, y) => {
|
||||
|
||||
return closestIndex
|
||||
}
|
||||
|
||||
// 曲线右击事件
|
||||
const handleCurveContextMenu = (curve, index, event) => {
|
||||
event.preventDefault()
|
||||
state.curveContextMenu.visible = true
|
||||
state.curveContextMenu.x = event.clientX
|
||||
state.curveContextMenu.y = event.clientY
|
||||
state.curveContextMenu.currentCurve = curve
|
||||
state.curveContextMenu.currentIndex = index
|
||||
state.currentDragTarget.index = index
|
||||
}
|
||||
|
||||
// 隐藏曲线右击菜单
|
||||
const hideCurveContextMenu = () => {
|
||||
state.curveContextMenu.visible = false
|
||||
state.curveContextMenu.currentIndex = -1
|
||||
}
|
||||
|
||||
// 曲线删除(仅UI,逻辑留空)
|
||||
const deleteCurveRoute = () => {
|
||||
if (state.currentDragTarget.index !== null) {
|
||||
state.mapRouteList.splice(state.currentDragTarget.index, 1)
|
||||
state.currentDragTarget.index = null
|
||||
}
|
||||
addEditHistory()
|
||||
hideCurveContextMenu()
|
||||
}
|
||||
|
||||
// 点击空白处关闭曲线菜单
|
||||
window.addEventListener('click', (e) => {
|
||||
if (state.curveContextMenu.visible) {
|
||||
const menu = document.querySelector('.context-menu')
|
||||
if (menu && !menu.contains(e.target)) {
|
||||
hideCurveContextMenu()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 直角拐角控制点计算
|
||||
function getRightAngleControlPoints(direction, start, end, offset = 0) {
|
||||
let corner
|
||||
if (direction === 'leftTop') {
|
||||
corner = { x: Math.min(start.x, end.x), y: Math.min(start.y, end.y) }
|
||||
} else if (direction === 'rightBottom') {
|
||||
corner = { x: Math.max(start.x, end.x), y: Math.max(start.y, end.y) }
|
||||
} else if (direction === 'leftBottom') {
|
||||
corner = { x: Math.min(start.x, end.x), y: Math.max(start.y, end.y) }
|
||||
} else if (direction === 'rightTop') {
|
||||
corner = { x: Math.max(start.x, end.x), y: Math.min(start.y, end.y) }
|
||||
} else {
|
||||
corner = { x: end.x, y: start.y }
|
||||
}
|
||||
// 计算单位向量
|
||||
const getUnit = (from, to) => {
|
||||
const dx = from.x - to.x
|
||||
const dy = from.y - to.y
|
||||
const len = Math.sqrt(dx * dx + dy * dy) || 1
|
||||
return { x: dx / len, y: dy / len }
|
||||
}
|
||||
// 控制点分别在拐点往起点/终点方向各偏移offset像素
|
||||
const u1 = getUnit(corner, start)
|
||||
const u2 = getUnit(corner, end)
|
||||
const beginControl = { x: corner.x + u1.x * offset, y: corner.y + u1.y * offset }
|
||||
const endControl = { x: corner.x + u2.x * offset, y: corner.y + u2.y * offset }
|
||||
return { beginControl, endControl }
|
||||
}
|
||||
// 设置曲线为直角拐角
|
||||
function setCurveRightAngle(direction) {
|
||||
const curve = state.curveContextMenu.currentCurve
|
||||
if (!curve) return
|
||||
const start = { x: curve.startPointX, y: curve.startPointY }
|
||||
const end = { x: curve.endPointX, y: curve.endPointY }
|
||||
const { beginControl, endControl } = getRightAngleControlPoints(direction, start, end)
|
||||
curve.beginControlX = beginControl.x
|
||||
curve.beginControlY = beginControl.y
|
||||
curve.endControlX = endControl.x
|
||||
curve.endControlY = endControl.y
|
||||
curve.method = 1
|
||||
hideCurveContextMenu()
|
||||
}
|
||||
|
||||
// 动态判断可用直角拐角方向
|
||||
function getAvailableRightAngleDirections(curve) {
|
||||
if (!curve) return []
|
||||
const sx = curve.startPointX,
|
||||
sy = curve.startPointY,
|
||||
ex = curve.endPointX,
|
||||
ey = curve.endPointY
|
||||
const dx = ex - sx
|
||||
const dy = ey - sy
|
||||
if (dx === 0 || dy === 0) return []
|
||||
if (dx * dy > 0) return ['leftBottom', 'rightTop']
|
||||
if (dx * dy < 0) return ['leftTop', 'rightBottom']
|
||||
return []
|
||||
}
|
||||
// 方向label
|
||||
function rightAngleDirectionLabel(dir) {
|
||||
switch (dir) {
|
||||
case 'rightTop':
|
||||
return '右上直角拐角'
|
||||
case 'rightBottom':
|
||||
return '右下直角拐角'
|
||||
case 'leftTop':
|
||||
return '左上直角拐角'
|
||||
case 'leftBottom':
|
||||
return '左下直角拐角'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
//右击编辑路线
|
||||
const contextMenuEditRoute = () => {
|
||||
removeEventListener() //移除监听
|
||||
let item = state.mapRouteList[state.currentDragTarget.index]
|
||||
editMapRouteDialogRef.value.open(JSON.parse(JSON.stringify(item)))
|
||||
}
|
||||
|
||||
// 新增:处理节点点击,显示节点locationX/locationY
|
||||
function handleNodeClick(item) {
|
||||
state.actualLocation.x = item.actualLocationX ? Number(item.actualLocationX).toFixed(3) : ''
|
||||
state.actualLocation.y = item.actualLocationY ? Number(item.actualLocationY).toFixed(3) : ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
Loading…
Reference in New Issue
Block a user