diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/DockIndicator.vue b/AutoRobot/Windows/Robot/Web/src/DockLayout/DockIndicator.vue index 2fc380d..b2c6f98 100644 --- a/AutoRobot/Windows/Robot/Web/src/DockLayout/DockIndicator.vue +++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/DockIndicator.vue @@ -194,6 +194,7 @@ { // 安全版本的targetRect,过滤掉可能的无效属性 const safeTargetRect = computed(() => getSafeTargetRect(props.targetRect)); +// 子区域指示器位置计算(相对于.indicator-center-area) +const subAreaIndicatorStyle = computed(() => { + const centerSize = 235; // 中心指示区尺寸 (indicator-center-area) + const padding = 8; // 内边距和间距 + const centerOffset = centerSize / 2; + + return { + // 上区指示器:位于中心指示区顶部,距离顶部padding像素 + topArea: { + position: 'absolute', + top: `${padding}px`, + left: `${centerOffset}px`, + transform: 'translateX(-50%)', + zIndex: 2 + }, + // 下区指示器:位于中心指示区底部,距离底部padding像素 + bottomArea: { + position: 'absolute', + bottom: `${padding}px`, + left: `${centerOffset}px`, + transform: 'translateX(-50%)', + zIndex: 2 + }, + // 左区指示器:位于中心指示区左侧,距离左侧padding像素 + leftArea: { + position: 'absolute', + top: `${centerOffset}px`, + left: `${padding}px`, + transform: 'translateY(-50%)', + zIndex: 2 + }, + // 右区指示器:位于中心指示区右侧,距离右侧padding像素 + rightArea: { + position: 'absolute', + top: `${centerOffset}px`, + right: `${padding}px`, + transform: 'translateY(-50%)', + zIndex: 2 + } + }; +}); + // 处理鼠标进入指示器 const handleMouseEnter = (zone) => { // 清除可能存在的离开定时器 @@ -1048,9 +1095,9 @@ watch(activeDockZone, (newZone) => { /* 上区指示器:位于中心指示区上方指示器的上方4个像素处 */ .dock-top-area { position: absolute; - top: 51px; /* 向上偏移,确保距离中心指示区上方指示器上边缘4个像素 */ - left: 50%; - transform: translateX(-50%); + top: 8px; /* 相对于indicator-center-area顶部的距离 */ + left: 50%; /* 相对于indicator-center-area左侧50%的位置 */ + transform: translateX(-50%); /* 向左移动自身宽度的50%,实现水平居中 */ opacity: 0.7; /* 默认半透明 */ transition: opacity 0.2s; z-index: 2; /* 确保在中心指示区上方 */ @@ -1059,9 +1106,9 @@ watch(activeDockZone, (newZone) => { /* 左区指示器:位于中心指示区左侧指示器的右侧4个像素处 */ .dock-left-area { position: absolute; - top: 50%; - left: 51px; /* 向右偏移,确保距离中心指示区左侧指示器右边缘4个像素 */ - transform: translateY(-50%); + top: 50%; /* 相对于indicator-center-area顶部50%的位置 */ + left: 8px; /* 相对于indicator-center-area左侧的距离 */ + transform: translateY(-50%); /* 向上移动自身高度的50%,实现垂直居中 */ opacity: 0.7; /* 默认半透明 */ transition: opacity 0.2s; z-index: 2; /* 确保在中心指示区上方 */ @@ -1070,9 +1117,10 @@ watch(activeDockZone, (newZone) => { /* 右区指示器:位于中心指示区右侧指示器的左侧4个像素处 */ .dock-right-area { position: absolute; - top: 50%; - right: 51px; /* 向左偏移,确保距离中心指示区右侧指示器左边缘4个像素 */ - transform: translateY(-50%); + top: 50%; /* 相对于indicator-center-area顶部50%的位置 */ + right: 8px; /* 相对于indicator-center-area右侧的距离 */ + transform: translateY(-50%); /* 向上移动自身高度的50%,实现垂直居中 */ + left: auto; /* 覆盖原有left属性 */ opacity: 0.7; /* 默认半透明 */ transition: opacity 0.2s; z-index: 2; /* 确保在中心指示区上方 */ @@ -1081,9 +1129,10 @@ watch(activeDockZone, (newZone) => { /* 下区指示器:位于中心指示区下方指示器的下方4个像素处 */ .dock-bottom-area { position: absolute; - bottom: 51px; /* 向上偏移,确保距离中心指示区下方指示器下边缘4个像素 */ - left: 50%; - transform: translateX(-50%); + bottom: 8px; /* 相对于indicator-center-area底部的距离 */ + left: 50%; /* 相对于indicator-center-area左侧50%的位置 */ + transform: translateX(-50%); /* 向左移动自身宽度的50%,实现水平居中 */ + top: auto; /* 覆盖原有top属性 */ opacity: 0.7; /* 默认半透明 */ transition: opacity 0.2s; z-index: 2; /* 确保在中心指示区上方 */ diff --git a/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue b/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue index 42fac18..4dddc8f 100644 --- a/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue +++ b/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue @@ -820,7 +820,7 @@ const getMainAreaResizeBarStyle = (resizeBar) => { // 计算属性 const hideEdgeIndicators = computed(() => { - return !hasAreasInMainContent.value; + return false; // 始终显示边缘指示器 }); // 设置事件总线监听器 diff --git a/AutoRobot/Windows/Robot/Web/src/utils/debounce.js b/AutoRobot/Windows/Robot/Web/src/utils/debounce.js new file mode 100644 index 0000000..9be29b2 --- /dev/null +++ b/AutoRobot/Windows/Robot/Web/src/utils/debounce.js @@ -0,0 +1,59 @@ +/** + * 可取消的防抖函数实现 + * @param {Function} func - 要执行的函数 + * @param {number} wait - 等待时间(毫秒) + * @returns {Function} 防抖后的函数,包含cancel方法 + */ +export const debounce = (func, wait) => { + let timeout; + + const debounced = function(...args) { + const context = this; + + const later = () => { + timeout = null; + func.apply(context, args); + }; + + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + + // 添加取消方法 + debounced.cancel = () => { + clearTimeout(timeout); + timeout = null; + }; + + return debounced; +}; + +/** + * 可取消的节流函数实现 + * @param {Function} func - 要执行的函数 + * @param {number} limit - 时间限制(毫秒) + * @returns {Function} 节流后的函数,包含cancel方法 + */ +export const throttle = (func, limit) => { + let inThrottle; + + const throttled = function(...args) { + const context = this; + + if (!inThrottle) { + func.apply(context, args); + inThrottle = true; + + setTimeout(() => { + inThrottle = false; + }, limit); + } + }; + + // 添加取消方法 + throttled.cancel = () => { + inThrottle = false; + }; + + return throttled; +};