131 lines
3.6 KiB
Vue
131 lines
3.6 KiB
Vue
<template>
|
|
<div
|
|
@mousedown="startSelection"
|
|
@mousemove="updateSelection"
|
|
@mouseup="endSelection"
|
|
style="position: relative; width: 100vw; height: 100vh"
|
|
>
|
|
<!-- 绘制所有框选区域 -->
|
|
<div
|
|
v-for="(rect, index) in selectionRects"
|
|
:key="index"
|
|
:style="{
|
|
position: 'absolute',
|
|
left: `${rect.left}px`,
|
|
top: `${rect.top}px`,
|
|
width: `${rect.width}px`,
|
|
height: `${rect.height}px`,
|
|
backgroundColor: 'rgba(0, 0, 255, 0.2)',
|
|
border: '1px solid blue'
|
|
}"
|
|
></div>
|
|
|
|
<!-- 绘制点位 -->
|
|
<div
|
|
v-for="(point, index) in points"
|
|
:key="index"
|
|
:style="{
|
|
position: 'absolute',
|
|
left: `${point.x}px`,
|
|
top: `${point.y}px`,
|
|
width: '10px',
|
|
height: '10px',
|
|
backgroundColor: selectedPoints.includes(point) ? 'red' : 'green',
|
|
borderRadius: '50%'
|
|
}"
|
|
></div>
|
|
|
|
<!-- 确认按钮 -->
|
|
<button @click="confirmSelection" style="position: fixed; bottom: 20px; right: 20px">
|
|
确认
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { ref } from 'vue'
|
|
|
|
export default {
|
|
setup() {
|
|
const points = ref([
|
|
{ x: 10, y: 10 },
|
|
{ x: 30, y: 100 },
|
|
{ x: 40, y: 40 },
|
|
{ x: 230, y: 400 },
|
|
{ x: 750, y: 640 }
|
|
])
|
|
|
|
const isSelecting = ref(false)
|
|
const startPos = ref({ x: 0, y: 0 })
|
|
const currentRect = ref({ left: 0, top: 0, width: 0, height: 0 })
|
|
const selectionRects = ref([]) // 存储所有框选区域
|
|
const selectedPoints = ref([]) // 存储选中的点位
|
|
const selectedPointsInOrder = ref([]) // 按照框选顺序存储选中的点位
|
|
|
|
// 开始框选
|
|
const startSelection = (event) => {
|
|
isSelecting.value = true
|
|
startPos.value = { x: event.clientX, y: event.clientY }
|
|
currentRect.value = { left: event.clientX, top: event.clientY, width: 0, height: 0 }
|
|
}
|
|
|
|
// 更新框选区域
|
|
const updateSelection = (event) => {
|
|
if (isSelecting.value) {
|
|
currentRect.value = {
|
|
left: Math.min(startPos.value.x, event.clientX),
|
|
top: Math.min(startPos.value.y, event.clientY),
|
|
width: Math.abs(event.clientX - startPos.value.x),
|
|
height: Math.abs(event.clientY - startPos.value.y)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 结束框选
|
|
const endSelection = () => {
|
|
if (isSelecting.value) {
|
|
isSelecting.value = false
|
|
selectionRects.value.push({ ...currentRect.value }) // 保存当前框选区域
|
|
checkPointsInSelection(currentRect.value) // 检查当前框选区域内的点位
|
|
}
|
|
}
|
|
|
|
// 检查点位是否在框选区域内
|
|
const checkPointsInSelection = (rect) => {
|
|
points.value.forEach((point) => {
|
|
if (
|
|
point.x >= rect.left &&
|
|
point.x <= rect.left + rect.width &&
|
|
point.y >= rect.top &&
|
|
point.y <= rect.top + rect.height &&
|
|
!selectedPoints.value.includes(point) // 避免重复添加
|
|
) {
|
|
selectedPoints.value.push(point)
|
|
selectedPointsInOrder.value.push(point) // 按照框选顺序添加
|
|
}
|
|
})
|
|
}
|
|
|
|
// 确认选择
|
|
const confirmSelection = () => {
|
|
console.log('Selected Points in Order:', selectedPointsInOrder.value)
|
|
// 清除框选区域和选中的点位
|
|
selectionRects.value = []
|
|
selectedPoints.value = []
|
|
selectedPointsInOrder.value = []
|
|
}
|
|
|
|
return {
|
|
points,
|
|
isSelecting,
|
|
selectionRects,
|
|
selectedPoints,
|
|
startSelection,
|
|
updateSelection,
|
|
endSelection,
|
|
confirmSelection
|
|
}
|
|
}
|
|
}
|
|
</script>
|