diff --git a/src/App.vue b/src/App.vue index fa1e920..b5c4560 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1222,6 +1222,9 @@ async function handleVoiceQueryComplete(text: string) { /* 平板/大屏 (769px+) */ @media (min-width: 769px) { + .subtitle-overlay { + width: 80%; + } } /* 横屏模式 */ diff --git a/src/components/SubtitlePanel.vue b/src/components/SubtitlePanel.vue index 806e831..13544ef 100644 --- a/src/components/SubtitlePanel.vue +++ b/src/components/SubtitlePanel.vue @@ -316,20 +316,59 @@ const aiSubtitleTextRef = ref(null); const aiFontSize = ref(18); const aiTextOverflow = ref(false); -// 计算AI字幕字号:根据文本长度动态调整 +// 检测是否为 1440×2560 目标分辨率 +const isTargetResolution = ref(false); + +/** + * 检测当前视口是否为 1440×2560 分辨率 + * 使用 window.innerWidth 和 innerHeight 精确匹配 + */ +const checkResolution = () => { + const TARGET_WIDTH = 1440; + const TARGET_HEIGHT = 2560; + console.log("------------", window.innerWidth, window.innerHeight); + isTargetResolution.value = + (window.innerWidth === TARGET_WIDTH && + window.innerHeight === TARGET_HEIGHT) || + (window.innerWidth > 1000 && window.innerHeight > 1680); +}; + +/** + * 获取目标分辨率下的字号基准值 + * 1440×2560 下使用更大的字号以确保清晰可读 + */ +const getTargetFontSizeBase = (textLength: number): number => { + if (textLength <= 50) return 36; + if (textLength <= 100) return 32; + if (textLength <= 200) return 28; + if (textLength <= 400) return 24; + return 22; +}; + +/** + * 获取普通分辨率下的字号基准值 + */ +const getNormalFontSizeBase = (textLength: number): number => { + if (textLength <= 50) return 18; + if (textLength <= 100) return 16; + if (textLength <= 200) return 14; + if (textLength <= 400) return 13; + return 12; +}; + +// 计算AI字幕字号:根据分辨率和文本长度动态调整 const computeAIFontSize = () => { const text = props.aiSubtitle; + console.log("------------", text); if (!text) { - aiFontSize.value = 18; + aiFontSize.value = isTargetResolution.value ? 36 : 18; return; } const len = text.length; - if (len <= 50) aiFontSize.value = 18; - else if (len <= 100) aiFontSize.value = 16; - else if (len <= 200) aiFontSize.value = 14; - else if (len <= 400) aiFontSize.value = 13; - else aiFontSize.value = 12; + aiFontSize.value = isTargetResolution.value + ? getTargetFontSizeBase(len) + : getNormalFontSizeBase(len); }; // 检测AI字幕是否溢出 @@ -400,12 +439,30 @@ const handleClickOutside = (e: MouseEvent) => { } }; +/** + * 处理视口尺寸变化:重新检测分辨率并更新字号 + */ +const handleResize = () => { + const wasTarget = isTargetResolution.value; + checkResolution(); + // 如果分辨率状态变化,重新计算字号 + if (wasTarget !== isTargetResolution.value) { + computeAIFontSize(); + } +}; + onMounted(() => { document.addEventListener("click", handleClickOutside); + // 初始检测分辨率 + checkResolution(); + computeAIFontSize(); + // 监听视口尺寸变化 + window.addEventListener("resize", handleResize); }); onBeforeUnmount(() => { document.removeEventListener("click", handleClickOutside); + window.removeEventListener("resize", handleResize); }); // ===== 消息配对 ===== @@ -790,6 +847,7 @@ const scrollToBottom = () => { .bubble-text { font-size: 14px; line-height: 1.6; + letter-spacing: 0.2px; word-break: break-word; overflow: hidden; transition: max-height 0.35s ease; @@ -874,6 +932,7 @@ const scrollToBottom = () => { .merged-text { font-size: 14px; line-height: 1.6; + letter-spacing: 0.2px; word-break: break-word; overflow: hidden; transition: max-height 0.35s ease; @@ -904,4 +963,129 @@ const scrollToBottom = () => { } } } + +/* ===== 1440×2560 分辨率专用样式 ===== */ +@media (min-width: 1000px) and (min-height: 1680px) { + /* 一级正文:气泡/合并文本/占位符 */ + .bubble-text, + .merged-text, + .subtitle-placeholder { + font-size: 24px; + line-height: 1.75; + letter-spacing: 0.5px; + font-weight: 400; + } + + /* AI字幕:字号由 JavaScript 动态控制,此处仅设置辅助样式 */ + .ai-subtitle-text { + line-height: 1.75; + letter-spacing: 0.6px; + font-weight: 400; + text-shadow: 0 2px 8px rgba(0, 0, 0, 0.7); + } + + /* 二级UI:下拉框/菜单项 */ + .dropdown-trigger, + .dropdown-item { + font-size: 20px; + font-weight: 500; + } + + /* 三级辅助:展开按钮 */ + .expand-btn { + font-size: 17px; + padding: 6px 18px; + } + + /* 字幕容器:背景与边框适配大字号 */ + .ai-subtitle-bar { + padding: 18px 24px; + border-radius: 12px; + background: linear-gradient( + 135deg, + rgba(108, 140, 255, 0.12) 0%, + rgba(79, 110, 247, 0.06) 100% + ); + border: 1px solid rgba(108, 140, 255, 0.15); + } + + /* 气泡容器:间距与圆角适配 */ + .bubble-body { + padding: 16px 20px; + border-radius: 20px; + } + + .chat-bubble.bubble-user .bubble-body { + border-radius: 20px 20px 6px 20px; + margin-left: 36px; + } + + .chat-bubble.bubble-ai .bubble-body { + border-radius: 20px 20px 20px 6px; + margin-right: 36px; + } + + .merged-bubble { + border-radius: 18px; + } + + .merged-user-section, + .merged-ai-section { + padding: 16px 20px; + } + + /* 头部区域:间距放大 */ + .subtitle-header { + padding-bottom: 14px; + margin-bottom: 14px; + } + + .dropdown-trigger { + padding: 14px 22px; + border-radius: 14px; + } + + .dropdown-item { + padding: 16px 22px; + border-radius: 12px; + } + + /* 下拉菜单宽度适配 */ + .dropdown-menu { + min-width: 240px; + padding: 8px; + border-radius: 16px; + } + + /* 滚动指示器:尺寸适配 */ + .scroll-hint { + width: 40px; + height: 40px; + margin-top: 12px; + } + + /* 聊天列表间距 */ + .chat-list { + gap: 12px; + } + + .merged-list { + gap: 12px; + } + + .bubble-text { + font-size: 28px !important; + } + + /* 折叠高度适配(按新字号比例) */ + .bubble-text.collapsed, + .merged-text.collapsed { + max-height: 6em; + } + + .bubble-text.collapsed::after, + .merged-text.collapsed::after { + height: 3em; + } +}