fix: 修正手機端詞彙popup定位問題

- 解決手機版popup容易被屏幕邊緣截掉的問題
- 實現響應式popup寬度:min(320px, calc(100vw - 32px))
- 針對手機端(≤640px)特殊處理:popup自動居中顯示
- 優化邊界檢測邏輯,確保popup始終在可視範圍內
- 大屏幕保持智能定位,小屏幕採用安全居中策略
- 添加動態寬度計算,適應不同屏幕尺寸
- 預留最小邊距16px,避免popup貼邊顯示

修正後手機端用戶體驗大幅改善,popup不再被截掉。

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
鄭沛軒 2025-09-20 20:13:20 +08:00
parent be236f7216
commit 453ecd6d1c
1 changed files with 29 additions and 5 deletions

View File

@ -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] && (
<div
className="fixed z-50 bg-white rounded-2xl shadow-2xl border-0 w-80 backdrop-blur-sm"
className="fixed z-50 bg-white rounded-2xl shadow-2xl border-0 backdrop-blur-sm"
style={{
left: `${popupPosition.x}px`,
top: `${popupPosition.y}px`,
transform: popupPosition.showBelow
? 'translate(-50%, 8px)'
: 'translate(-50%, calc(-100% - 8px))',
width: 'min(320px, calc(100vw - 32px))', // 響應式寬度,手機端自動收縮
maxHeight: '85vh',
overflowY: 'auto',
background: 'rgba(255, 255, 255, 0.98)',