fix(tts): properly follow tts reading position in scrolled mode (#3581)

This commit is contained in:
Huang Xin
2026-03-22 01:08:45 +08:00
committed by GitHub
parent f5df80f154
commit 0177a03a90
4 changed files with 12 additions and 16 deletions
@@ -53,7 +53,7 @@ const ProgressBar: React.FC<ProgressBarProps> = ({
const pageInfo = bookData?.isFixedLayout ? section : pageinfo;
const progressInfo = formatProgress(pageInfo?.current, pageInfo?.total, template, localize, lang);
const { sectionPage: current = 0, sectionPages: total = 0 } = view?.renderer || {};
const { page: current = 0, pages: total = 0 } = view?.renderer || {};
const pagesLeft = Math.min(
Math.max(total - current, 1),
pageInfo ? pageInfo.total - pageInfo.current : total,
@@ -149,11 +149,9 @@ export const useTTSControl = ({ bookKey, onRequestHidePanel }: UseTTSControlProp
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 { start, end, sideProp } = view.renderer;
const rangeTop = rect[sideProp === 'height' ? 'y' : 'x'];
const rangeBottom = rangeTop + rect[sideProp === 'height' ? 'height' : 'width'];
const showHeader = viewSettings.showHeader;
const showFooter = viewSettings.showFooter;
@@ -161,11 +159,11 @@ export const useTTSControl = ({ bookKey, onRequestHidePanel }: UseTTSControlProp
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);
const outOfView =
rangeBottom > end - footerScrollOverlap - scrollingOverlap ||
rangeTop < start + headerScrollOverlap + scrollingOverlap;
if (outOfView) {
view.renderer.scrollToAnchor?.(range);
}
}
};
+2 -4
View File
@@ -66,10 +66,8 @@ export interface FoliateView extends HTMLElement {
viewSize: number; // whole document view height
start: number;
end: number;
page: number; // rendered page index (0-based)
pages: number; // rendered page count
sectionPage: number; // current page index in the current section
sectionPages: number; // page count in the current section
page: number; // section page index (0-based)
pages: number; // section page count
atStart: boolean;
atEnd: boolean;
containerPosition: number;