fix(tts): scroll more accurately to the highlighted text in TTS when header/footer bars are shown (#2242)

This commit is contained in:
Huang Xin
2025-10-15 23:50:56 +08:00
committed by GitHub
parent 7f5b6959e1
commit 9dda5d4c88
5 changed files with 31 additions and 14 deletions
@@ -68,8 +68,8 @@ const SectionInfo: React.FC<SectionInfoProps> = ({
}
: {
top: `${topInset}px`,
insetInlineStart: `calc(${horizontalGap / 2}% + ${contentInsets.left}px)`,
width: `calc(100% - ${contentInsets.left + contentInsets.right}px)`,
paddingInlineStart: `calc(${horizontalGap / 2}% + ${contentInsets.left}px)`,
width: '100%',
}
}
>
@@ -11,7 +11,7 @@ import { BookSearchConfig, BookSearchResult } from '@/types/book';
import { useResponsiveSize } from '@/hooks/useResponsiveSize';
import { debounce } from '@/utils/debounce';
import { isCJKStr } from '@/utils/lang';
import { createRejecttFilter } from '@/utils/node';
import { createRejectFilter } from '@/utils/node';
import Dropdown from '@/components/Dropdown';
import SearchOptions from './SearchOptions';
@@ -127,7 +127,7 @@ const SearchBar: React.FC<SearchBarProps> = ({
...searchConfig,
index,
query: term,
acceptNode: createRejecttFilter({
acceptNode: createRejectFilter({
tags: primaryLang.startsWith('ja') ? ['rt'] : [],
}),
});
@@ -208,6 +208,30 @@ const TTSControl: React.FC<TTSControlProps> = ({ bookKey, gridInsets }) => {
viewSettings.ttsLocation = cfi || '';
setViewSettings(bookKey, viewSettings);
}
if (!view.renderer.scrolled) {
view.renderer.scrollToAnchor(range);
} else {
const rect = range.getBoundingClientRect();
const { start, size, viewSize, sideProp } = view.renderer;
const positionStart = rect[sideProp === 'height' ? 'y' : 'x'] + viewSettings.marginTopPx;
const positionEnd = rect[sideProp === 'height' ? 'height' : 'width'] + positionStart;
const offsetStart = view.book.dir === 'rtl' ? viewSize - positionStart : positionStart;
const offsetEnd = view.book.dir === 'rtl' ? viewSize - positionEnd : positionEnd;
const showHeader = viewSettings.showHeader;
const showFooter = viewSettings.showFooter;
const showBarsOnScroll = viewSettings.showBarsOnScroll;
const headerScrollOverlap = showHeader && showBarsOnScroll ? 44 : 0;
const footerScrollOverlap = showFooter && showBarsOnScroll ? 44 : 0;
const scrollingOverlap = viewSettings.scrollingOverlap;
const endInNextView = offsetEnd > start + size - footerScrollOverlap - scrollingOverlap;
const startInPrevView = offsetStart < start + headerScrollOverlap + scrollingOverlap;
if (endInNextView || startInPrevView) {
const scrollTo = offsetStart - headerScrollOverlap - scrollingOverlap;
view.renderer.scrollToAnchor(scrollTo / viewSize);
}
}
};
ttsController.addEventListener('tts-speak-mark', handleSpeakMark);