diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index cdf511a..c9518fe 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -1425,98 +1425,107 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF - {/* 🆕 标签悬停预览弹窗 */} - {tagPreview && ( -
{ - // 鼠标进入预览弹窗,取消隐藏 - if (previewTimeoutRef.current) { - clearTimeout(previewTimeoutRef.current); - previewTimeoutRef.current = null; - } - }} - onMouseLeave={() => { - // 鼠标离开预览弹窗,隐藏 - setTagPreview(null); - }} - > - {/* 图片全貌 */} -
- {tagPreview.name} - {/* 如果是物品标签,显示标注位置 */} - {tagPreview.pickedObject && ( - <> - {/* 标注点 */} -
- {/* 序号标记 */} -
- {/* 脉冲动画背景 */} -
- {/* 主标记点 */} -
- - - + {/* 🆕 标签悬停预览弹窗 - 固定显示在标签上方 */} + {tagPreview && (() => { + // 计算弹窗位置,确保不超出视口 + const previewWidth = 240; + const previewHeight = 280; // 预估高度 + const padding = 16; + + // 水平位置:居中对齐标签,但确保不超出左右边界 + let left = tagPreview.x - previewWidth / 2; + if (left < padding) left = padding; + if (left + previewWidth > window.innerWidth - padding) { + left = window.innerWidth - previewWidth - padding; + } + + // 垂直位置:显示在标签上方 + let top = tagPreview.y - previewHeight - 12; + if (top < padding) { + // 如果上方空间不够,显示在标签下方 + top = tagPreview.y + 30; + } + + return ( +
{ + // 鼠标进入预览弹窗,取消隐藏 + if (previewTimeoutRef.current) { + clearTimeout(previewTimeoutRef.current); + previewTimeoutRef.current = null; + } + }} + onMouseLeave={() => { + // 鼠标离开预览弹窗,隐藏 + setTagPreview(null); + }} + > + {/* 图片全貌 */} +
+ {tagPreview.name} + {/* 如果是物品标签,显示标注位置 */} + {tagPreview.pickedObject && ( + <> + {/* 标注点 */} +
+ {/* 序号标记 */} +
+ {/* 脉冲动画背景 */} +
+ {/* 主标记点 */} +
+ + + +
-
- {/* 物品名称标签 */} -
- {tagPreview.pickedObject.objectName} -
- - )} -
- {/* 底部信息 */} -
-
- {tagPreview.pickedObject ? tagPreview.pickedObject.objectName : tagPreview.name} + {/* 物品名称标签 */} +
+ {tagPreview.pickedObject.objectName} +
+ + )}
- {tagPreview.pickedObject && ( -
- {tagPreview.pickedObject.objectPosition} + {/* 底部信息 */} +
+
+ {tagPreview.pickedObject ? tagPreview.pickedObject.objectName : tagPreview.name}
- )} + {tagPreview.pickedObject && ( +
+ {tagPreview.pickedObject.objectPosition} +
+ )} +
- {/* 小三角箭头 */} -
-
- )} + ); + })()}
); }