mirror of
https://github.com/45Drives/cockpit-navigator.git
synced 2025-07-31 01:24:37 +02:00
add selection box
This commit is contained in:
parent
65e3936fda
commit
c4ef085c1f
79
navigator/src/components/DragSelectArea.vue
Normal file
79
navigator/src/components/DragSelectArea.vue
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<div v-show="dragging" class="fixed border-red-600/50 border border-solid bg-red-600/10 rounded-lg" ref="selectionBox"></div>
|
||||||
|
<div @mousedown="startDrag" v-bind="$attrs">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref, reactive, watch, onMounted, nextTick, onBeforeUnmount } from 'vue'
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
areaThreshold: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const selectionBox = ref();
|
||||||
|
const rect = reactive({ x1: null, y1: null, x2: null, y2: null });
|
||||||
|
const dragging = ref(false);
|
||||||
|
|
||||||
|
const startDrag = (event) => {
|
||||||
|
dragging.value = true;
|
||||||
|
rect.x1 = rect.x2 = event.clientX;
|
||||||
|
rect.y1 = rect.y2 = event.clientY;
|
||||||
|
window.addEventListener('mousemove', drag);
|
||||||
|
window.addEventListener('mouseup', endDrag, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const drag = (event) => {
|
||||||
|
rect.x2 = event.clientX;
|
||||||
|
rect.y2 = event.clientY;
|
||||||
|
}
|
||||||
|
|
||||||
|
const endDrag = (event) => {
|
||||||
|
window.removeEventListener('mousemove', drag);
|
||||||
|
window.removeEventListener('mouseup', endDrag, true);
|
||||||
|
drag(event);
|
||||||
|
let [x1, x2] = [rect.x1, rect.x2].sort((a, b) => a - b);
|
||||||
|
let [y1, y2] = [rect.y1, rect.y2].sort((a, b) => a - b);
|
||||||
|
const area = (x2 - x1) * (y2 - y1);
|
||||||
|
if (area > props.areaThreshold) {
|
||||||
|
event.stopPropagation();
|
||||||
|
emit('selectRectangle', { x1, y1, x2, y2 }, event);
|
||||||
|
}
|
||||||
|
dragging.value = false;
|
||||||
|
rect.x1 = rect.x2 = rect.y1 = rect.y2 = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
watch(rect, () => {
|
||||||
|
let [x1, x2] = [rect.x1, rect.x2].sort((a, b) => a - b);
|
||||||
|
let [y1, y2] = [rect.y1, rect.y2].sort((a, b) => a - b);
|
||||||
|
const area = (x2 - x1) * (y2 - y1);
|
||||||
|
dragging.value = area >= props.areaThreshold;
|
||||||
|
if (dragging.value) {
|
||||||
|
selectionBox.value.style.left = `${x1}px`;
|
||||||
|
selectionBox.value.style.top = `${y1}px`;
|
||||||
|
selectionBox.value.style.width = `${x2 - x1}px`;
|
||||||
|
selectionBox.value.style.height = `${y2 - y1}px`;
|
||||||
|
}
|
||||||
|
}, { immediate: true, deep: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
selectionBox,
|
||||||
|
rect,
|
||||||
|
dragging,
|
||||||
|
startDrag,
|
||||||
|
drag,
|
||||||
|
endDrag,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emits: [
|
||||||
|
'selectRectangle',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
x
Reference in New Issue
Block a user