diff --git a/frontend/components/ClickableTextV2.tsx b/frontend/components/ClickableTextV2.tsx index 3f81b62..494a6f1 100644 --- a/frontend/components/ClickableTextV2.tsx +++ b/frontend/components/ClickableTextV2.tsx @@ -75,17 +75,40 @@ export function ClickableTextV2({ const wordAnalysis = analysis?.[cleanWord] const rect = event.currentTarget.getBoundingClientRect() + const viewportWidth = window.innerWidth const viewportHeight = window.innerHeight + const popupWidth = 320 // popup寬度 w-80 = 320px const popupHeight = 400 // 估計popup高度 - // 智能定位:如果上方空間不足,就顯示在下方 + // 智能水平定位,適應不同屏幕尺寸 + let x = rect.left + rect.width / 2 + const actualPopupWidth = Math.min(popupWidth, viewportWidth - 32) // 實際popup寬度 + const halfPopupWidth = actualPopupWidth / 2 + const padding = 16 // 最小邊距 + + // 手機端特殊處理 + if (viewportWidth <= 640) { // sm斷點 + // 小屏幕時居中顯示,避免邊緣問題 + x = viewportWidth / 2 + } else { + // 大屏幕時智能調整位置 + if (x + halfPopupWidth + padding > viewportWidth) { + x = viewportWidth - halfPopupWidth - padding + } + if (x - halfPopupWidth < padding) { + x = halfPopupWidth + padding + } + } + + // 計算垂直位置 const spaceAbove = rect.top const spaceBelow = viewportHeight - rect.bottom + const showBelow = spaceAbove < popupHeight const position = { - x: rect.left + rect.width / 2, - y: spaceAbove >= popupHeight ? rect.top - 10 : rect.bottom + 10, - showBelow: spaceAbove < popupHeight + x: x, + y: showBelow ? rect.bottom + 10 : rect.top - 10, + showBelow: showBelow } if (wordAnalysis) { @@ -287,13 +310,14 @@ export function ClickableTextV2({ {/* 現代風格詞彙彈窗 */} {selectedWord && analysis?.[selectedWord] && (