diff --git a/components.d.ts b/components.d.ts index edaeed54..3906ae69 100644 --- a/components.d.ts +++ b/components.d.ts @@ -111,9 +111,11 @@ declare module 'vue' { IconFluentStar20Filled: typeof import('~icons/fluent/star20-filled')['default'] IconFluentStarAdd16Regular: typeof import('~icons/fluent/star-add16-regular')['default'] IconFluentTarget20Regular: typeof import('~icons/fluent/target20-regular')['default'] + IconFluentTextAlignLeft16Regular: typeof import('~icons/fluent/text-align-left16-regular')['default'] IconFluentTextBulletListSquare20Regular: typeof import('~icons/fluent/text-bullet-list-square20-regular')['default'] IconFluentTextEditStyle20Regular: typeof import('~icons/fluent/text-edit-style20-regular')['default'] IconFluentTextListAbcUppercaseLtr20Regular: typeof import('~icons/fluent/text-list-abc-uppercase-ltr20-regular')['default'] + IconFluentTextParagraph16Regular: typeof import('~icons/fluent/text-paragraph16-regular')['default'] IconFluentTextUnderlineDouble20Regular: typeof import('~icons/fluent/text-underline-double20-regular')['default'] IconFluentTranslate16Regular: typeof import('~icons/fluent/translate16-regular')['default'] IconFluentTranslateOff16Regular: typeof import('~icons/fluent/translate-off16-regular')['default'] diff --git a/src/pages/article/BookDetail.vue b/src/pages/article/BookDetail.vue index 5613081f..8806d4c6 100644 --- a/src/pages/article/BookDetail.vue +++ b/src/pages/article/BookDetail.vue @@ -9,7 +9,16 @@ import BaseButton from '@/components/BaseButton.vue' import { useRoute, useRouter } from 'vue-router' import EditBook from '@/pages/article/components/EditBook.vue' import { computed, onMounted, onUnmounted, watch } from 'vue' -import { _dateFormat, _getDictDataByUrl, isMobile, msToHourMinute, resourceWrap, total, useNav, _nextTick } from '@/utils' +import { + _dateFormat, + _getDictDataByUrl, + isMobile, + msToHourMinute, + resourceWrap, + total, + useNav, + _nextTick, +} from '@/utils' import { getDefaultArticle, getDefaultDict } from '@/types/func.ts' import Toast from '@/components/base/toast/Toast.ts' import ArticleAudio from '@/pages/article/components/ArticleAudio.vue' @@ -109,12 +118,19 @@ async function init() { onMounted(() => { init() - if (displayMode === 'typing-style') { - positionTranslations() - } + window.addEventListener('resize', handleResize) }) +watch( + () => selectArticle.id, + () => { + if (displayMode === 'typing-style') { + } + positionTranslations() + } +) + onUnmounted(() => { window.removeEventListener('resize', handleResize) }) @@ -219,21 +235,21 @@ interface ParsedParagraph { function parseTextToSections(text: string, textTranslate: string): ParsedParagraph[] { if (!text) return [] - + // 按段落分割(双换行) const textParagraphs = text.split('\n\n').filter(p => p.trim()) const translateParagraphs = textTranslate ? textTranslate.split('\n\n').filter(p => p.trim()) : [] - + // 句子分割正则:按句号、问号、感叹号分割,但保留标点 const sentenceRegex = /([^.!?]+[.!?]+)/g - + return textParagraphs.map((para, paraIndex) => { // 分割句子 const sentences = para.match(sentenceRegex) || [para] - const translateSentences = translateParagraphs[paraIndex] - ? (translateParagraphs[paraIndex].match(sentenceRegex) || [translateParagraphs[paraIndex]]) + const translateSentences = translateParagraphs[paraIndex] + ? translateParagraphs[paraIndex].match(sentenceRegex) || [translateParagraphs[paraIndex]] : [] - + return { sentences: sentences.map((sent, sentIndex) => ({ text: sent.trim(), @@ -251,40 +267,32 @@ const parsedArticle = $computed(() => { // 定位翻译到原文下方 function positionTranslations() { - if (!parsedArticle || isMob || !articleWrapperRef) return - - return new Promise(resolve => { - _nextTick(() => { - if (!articleWrapperRef) { - resolve() - return - } - - const articleRect = articleWrapperRef.getBoundingClientRect() - - parsedArticle?.forEach((paragraph, paraIndex) => { - paragraph.sentences.forEach((sentence, sentIndex) => { - const location = `${paraIndex}-${sentIndex}` - const sentenceClassName = `.sentence-${location}` - const sentenceEl = articleWrapperRef?.querySelector(sentenceClassName) - const translateClassName = `.translate-${location}` - const translateEl = articleWrapperRef?.querySelector(translateClassName) as HTMLDivElement - - if (sentenceEl && translateEl && sentence.translate) { - const sentenceRect = sentenceEl.getBoundingClientRect() - translateEl.style.opacity = '1' - translateEl.style.top = sentenceRect.top - articleRect.top + 24 + 'px' - const spaceEl = translateEl.firstElementChild as HTMLElement - if (spaceEl) { - spaceEl.style.width = sentenceRect.left - articleRect.left + 'px' - } + // if ( isMob || !articleWrapperRef) return + _nextTick(() => { + const articleRect = articleWrapperRef.getBoundingClientRect() + console.log('articleRect',articleRect) + selectArticle.textTranslate.split('\n\n').forEach((paragraph, paraIndex) => { + paragraph.split('\n').forEach((sentence, sentIndex) => { + debugger + const location = `${paraIndex}-${sentIndex}` + const sentenceClassName = `.sentence-${location}` + const sentenceEl = articleWrapperRef?.querySelector(sentenceClassName) + const translateClassName = `.translate-${location}` + const translateEl = articleWrapperRef?.querySelector(translateClassName) as HTMLDivElement + + if (sentenceEl && translateEl && sentence) { + const sentenceRect = sentenceEl.getBoundingClientRect() + console.log('sentenceRect',sentenceEl.innerText, sentenceRect) + translateEl.style.opacity = '1' + translateEl.style.top = sentenceRect.top - articleRect.top + 24 + 'px' + const spaceEl = translateEl.firstElementChild as HTMLElement + if (spaceEl) { + spaceEl.style.width = sentenceRect.left - articleRect.left + 'px' } - }) + } }) - - resolve() - }, 300) - }) + }) + }, 300) } // 监听显示模式和文章变化,重新定位翻译 @@ -296,14 +304,16 @@ watch([() => displayMode, () => selectArticle.id, () => showTranslate], () => {