This commit is contained in:
2026-10-05 01:36:30 +07:00
parent 7208fffe44
commit 3a326d5472
6 changed files with 42 additions and 17 deletions
+33 -13
View File
@@ -32,8 +32,11 @@ const props = defineProps<{
screenPosition: number
}>()
const GRID_SIZE = 20
const emit = defineEmits<{
saveItem: [item: MapItem, hidden?: boolean]
dragging: [value: boolean]
giveApplication: [team: Team, application: Application]
addStep: []
edit: []
@@ -51,6 +54,7 @@ const emit = defineEmits<{
const mapScale = ref(1)
const mapOffset = ref({ x: 0, y: 0 })
const mapField = ref<HTMLElement>()
const previewScreen = computed(
() => props.screens.find((screen) => screen.status === 'connected') || props.screens[0],
)
@@ -69,30 +73,39 @@ const screenPlanModeOptions = [
{ label: 'Текст', value: 'SCREEN_MODE_TEXT' },
]
let dragState:
{ item: MapItem; startX: number; startY: number; itemX: number; itemY: number } | undefined
{ item: MapItem; offsetX: number; offsetY: number } | undefined
let panState: { startX: number; startY: number; offsetX: number; offsetY: number } | undefined
function getMapCoordinate(event: PointerEvent) {
const field = mapField.value
if (!field) return
const rect = field.getBoundingClientRect()
return {
x: (event.clientX - rect.left - field.clientLeft - mapOffset.value.x) / mapScale.value,
y: (event.clientY - rect.top - field.clientTop - mapOffset.value.y) / mapScale.value,
}
}
function startMapDrag(item: MapItem, event: PointerEvent) {
const point = getMapCoordinate(event)
if (!point) return
dragState = {
item,
startX: event.clientX,
startY: event.clientY,
itemX: item.x || 0,
itemY: item.y || 0,
offsetX: point.x - (item.x || 0),
offsetY: point.y - (item.y || 0),
}
emit('dragging', true)
window.addEventListener('pointermove', moveMapDrag)
window.addEventListener('pointerup', endMapDrag, { once: true })
window.addEventListener('pointercancel', endMapDrag, { once: true })
}
function moveMapDrag(event: PointerEvent) {
if (!dragState) return
const step = dragState.item.kind === 'team' ? 20 : 1
dragState.item.x =
Math.round((dragState.itemX + (event.clientX - dragState.startX) / mapScale.value) / step) *
step
dragState.item.y =
Math.round((dragState.itemY + (event.clientY - dragState.startY) / mapScale.value) / step) *
step
const point = getMapCoordinate(event)
if (!point) return
dragState.item.x = Math.round((point.x - dragState.offsetX) / GRID_SIZE) * GRID_SIZE
dragState.item.y = Math.round((point.y - dragState.offsetY) / GRID_SIZE) * GRID_SIZE
}
function endMapDrag() {
@@ -100,6 +113,9 @@ function endMapDrag() {
const item = dragState.item
dragState = undefined
window.removeEventListener('pointermove', moveMapDrag)
window.removeEventListener('pointerup', endMapDrag)
window.removeEventListener('pointercancel', endMapDrag)
emit('dragging', false)
emit('saveItem', item)
}
@@ -148,8 +164,12 @@ function zoomMap(event: WheelEvent) {
}
onBeforeUnmount(() => {
if (dragState) emit('dragging', false)
window.removeEventListener('pointermove', moveMapDrag)
window.removeEventListener('pointerup', endMapDrag)
window.removeEventListener('pointercancel', endMapDrag)
window.removeEventListener('pointermove', moveMapPan)
window.removeEventListener('pointerup', endMapPan)
})
</script>
@@ -165,7 +185,7 @@ onBeforeUnmount(() => {
<n-button size="small" @click="resetMapView">Сбросить</n-button>
</n-space>
</n-flex>
<div class="map-field" @pointerdown="startMapPan" @wheel="zoomMap">
<div ref="mapField" class="map-field" @pointerdown="startMapPan" @wheel="zoomMap">
<div
class="map-canvas"
:style="{ transform: `translate(${mapOffset.x}px, ${mapOffset.y}px) scale(${mapScale})` }"