添加拖拽指示区域半透明预览框功能
This commit is contained in:
@@ -1,5 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="visible" class="dock-indicator" :style="indicatorStyle">
|
<div v-if="visible" class="dock-indicator" :style="indicatorStyle">
|
||||||
|
<!-- 半透明区域框:根据活动区域显示 -->
|
||||||
|
<div
|
||||||
|
v-if="activeDockZone"
|
||||||
|
class="dock-preview-area"
|
||||||
|
:style="previewAreaStyle"
|
||||||
|
></div>
|
||||||
<!-- 1. 定义可复用组件(symbol):封装所有渐变和路径(只写一次) -->
|
<!-- 1. 定义可复用组件(symbol):封装所有渐变和路径(只写一次) -->
|
||||||
<svg width="0" height="0" viewBox="0 0 40 40" aria-hidden="true">
|
<svg width="0" height="0" viewBox="0 0 40 40" aria-hidden="true">
|
||||||
<defs>
|
<defs>
|
||||||
@@ -245,6 +251,60 @@ const activeDockZone = computed(() => {
|
|||||||
return 'center'
|
return 'center'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 计算半透明区域框的样式
|
||||||
|
const previewAreaStyle = computed(() => {
|
||||||
|
if (!activeDockZone.value) return {};
|
||||||
|
|
||||||
|
const { left, top, width, height } = props.targetRect;
|
||||||
|
const threshold = 0.25;
|
||||||
|
|
||||||
|
// 根据不同的活动区域计算预览区域的样式
|
||||||
|
switch (activeDockZone.value) {
|
||||||
|
case 'top':
|
||||||
|
return {
|
||||||
|
position: 'absolute',
|
||||||
|
left: `${left}px`,
|
||||||
|
top: `${top}px`,
|
||||||
|
width: `${width}px`,
|
||||||
|
height: `${height * threshold}px`
|
||||||
|
};
|
||||||
|
case 'bottom':
|
||||||
|
return {
|
||||||
|
position: 'absolute',
|
||||||
|
left: `${left}px`,
|
||||||
|
top: `${top + height * (1 - threshold)}px`,
|
||||||
|
width: `${width}px`,
|
||||||
|
height: `${height * threshold}px`
|
||||||
|
};
|
||||||
|
case 'left':
|
||||||
|
return {
|
||||||
|
position: 'absolute',
|
||||||
|
left: `${left}px`,
|
||||||
|
top: `${top}px`,
|
||||||
|
width: `${width * threshold}px`,
|
||||||
|
height: `${height}px`
|
||||||
|
};
|
||||||
|
case 'right':
|
||||||
|
return {
|
||||||
|
position: 'absolute',
|
||||||
|
left: `${left + width * (1 - threshold)}px`,
|
||||||
|
top: `${top}px`,
|
||||||
|
width: `${width * threshold}px`,
|
||||||
|
height: `${height}px`
|
||||||
|
};
|
||||||
|
case 'center':
|
||||||
|
return {
|
||||||
|
position: 'absolute',
|
||||||
|
left: `${left + width * threshold}px`,
|
||||||
|
top: `${top + height * threshold}px`,
|
||||||
|
width: `${width * (1 - 2 * threshold)}px`,
|
||||||
|
height: `${height * (1 - 2 * threshold)}px`
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 定义事件
|
// 定义事件
|
||||||
const emit = defineEmits(['zone-active'])
|
const emit = defineEmits(['zone-active'])
|
||||||
|
|
||||||
@@ -260,6 +320,15 @@ watch(activeDockZone, (newZone) => {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 半透明区域框样式 */
|
||||||
|
.dock-preview-area {
|
||||||
|
background-color: rgba(161, 169, 196, 0.3); /* 半透明背景 */
|
||||||
|
border: 2px dashed #61697E; /* 虚线边框 */
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 9998; /* 确保在指示器下方 */
|
||||||
|
transition: all 0.2s ease; /* 平滑过渡效果 */
|
||||||
|
}
|
||||||
|
|
||||||
/* 上指示器:定位在目标区域的顶端中间,上边缘距dock-layout上边缘5像素 */
|
/* 上指示器:定位在目标区域的顶端中间,上边缘距dock-layout上边缘5像素 */
|
||||||
.indicator-top {
|
.indicator-top {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
Reference in New Issue
Block a user