fix: implement viewport-based page navigation for EPUBs
- Replace spine-only navigation with scroll-based page navigation - nextPage: scroll down within chapter, only jump to next spine at chapter end - previousPage: scroll up within chapter, only jump to previous spine at chapter start - Use viewportHeight - 120 for accurate page height calculation - Fallback to spine-only navigation when page calculation not available
This commit is contained in:
@@ -22,31 +22,43 @@ export function createNavigationAPI() {
|
||||
readerEvents.emit("beforePageChange", state.currentReader);
|
||||
|
||||
if (state.currentReader.type === "ebook") {
|
||||
if (
|
||||
state.currentReader.currentSpineIndex <
|
||||
state.currentReader.cif.spine.length - 1
|
||||
) {
|
||||
state.currentReader.currentSpineIndex++;
|
||||
if (pageCalculationResult) {
|
||||
const container = document.getElementById("reader-content");
|
||||
if (container) {
|
||||
const viewportHeight = window.innerHeight;
|
||||
const target = getScrollPositionForPage(
|
||||
pageCalculationResult,
|
||||
state.currentReader.currentPage ||
|
||||
state.currentReader.currentSpineIndex + 1,
|
||||
viewportHeight,
|
||||
);
|
||||
if (
|
||||
target &&
|
||||
target.spineIndex !== state.currentReader.currentSpineIndex
|
||||
) {
|
||||
state.currentReader.currentSpineIndex = target.spineIndex;
|
||||
container.scrollTop = target.scrollTop;
|
||||
}
|
||||
const container = document.getElementById("reader-content");
|
||||
const viewportHeightAdjusted = window.innerHeight - 120;
|
||||
|
||||
if (pageCalculationResult) {
|
||||
const currentChapter = pageCalculationResult.chapterMap.get(
|
||||
state.currentReader.currentSpineIndex,
|
||||
);
|
||||
|
||||
if (currentChapter && container) {
|
||||
const currentPageInChapter = Math.floor(
|
||||
container.scrollTop / viewportHeightAdjusted,
|
||||
);
|
||||
const pagesInCurrentChapter =
|
||||
currentChapter.endPage - currentChapter.startPage + 1;
|
||||
|
||||
if (currentPageInChapter < pagesInCurrentChapter - 1) {
|
||||
// Still pages left in current chapter - just scroll down
|
||||
container.scrollTop =
|
||||
(currentPageInChapter + 1) * viewportHeightAdjusted;
|
||||
} else if (
|
||||
state.currentReader.currentSpineIndex <
|
||||
state.currentReader.cif.spine.length - 1
|
||||
) {
|
||||
// At end of chapter, move to next spine
|
||||
state.currentReader.currentSpineIndex++;
|
||||
renderSpineItem();
|
||||
}
|
||||
}
|
||||
renderSpineItem();
|
||||
} else {
|
||||
// Fallback: just move to next spine
|
||||
if (
|
||||
state.currentReader.currentSpineIndex <
|
||||
state.currentReader.cif.spine.length - 1
|
||||
) {
|
||||
state.currentReader.currentSpineIndex++;
|
||||
renderSpineItem();
|
||||
}
|
||||
}
|
||||
} else if (state.currentReader.type === "pdf") {
|
||||
const totalPages = state.readerMetadata?.total_pages || 0;
|
||||
@@ -80,28 +92,35 @@ export function createNavigationAPI() {
|
||||
readerEvents.emit("beforePageChange", state.currentReader);
|
||||
|
||||
if (state.currentReader.type === "ebook") {
|
||||
if (state.currentReader.currentSpineIndex > 0) {
|
||||
state.currentReader.currentSpineIndex--;
|
||||
if (pageCalculationResult) {
|
||||
const container = document.getElementById("reader-content");
|
||||
if (container) {
|
||||
const viewportHeight = window.innerHeight;
|
||||
const target = getScrollPositionForPage(
|
||||
pageCalculationResult,
|
||||
state.currentReader.currentPage ||
|
||||
state.currentReader.currentSpineIndex + 1,
|
||||
viewportHeight,
|
||||
);
|
||||
if (
|
||||
target &&
|
||||
target.spineIndex !== state.currentReader.currentSpineIndex
|
||||
) {
|
||||
state.currentReader.currentSpineIndex = target.spineIndex;
|
||||
container.scrollTop = target.scrollTop;
|
||||
}
|
||||
const container = document.getElementById("reader-content");
|
||||
const viewportHeightAdjusted = window.innerHeight - 120;
|
||||
|
||||
if (pageCalculationResult) {
|
||||
const currentChapter = pageCalculationResult.chapterMap.get(
|
||||
state.currentReader.currentSpineIndex,
|
||||
);
|
||||
|
||||
if (currentChapter && container) {
|
||||
const currentPageInChapter = Math.floor(
|
||||
container.scrollTop / viewportHeightAdjusted,
|
||||
);
|
||||
|
||||
if (currentPageInChapter > 0) {
|
||||
// Not at start of chapter - just scroll up
|
||||
container.scrollTop =
|
||||
(currentPageInChapter - 1) * viewportHeightAdjusted;
|
||||
} else if (state.currentReader.currentSpineIndex > 0) {
|
||||
// At start of chapter, move to previous spine
|
||||
state.currentReader.currentSpineIndex--;
|
||||
renderSpineItem();
|
||||
}
|
||||
}
|
||||
renderSpineItem();
|
||||
} else {
|
||||
// Fallback: just move to previous spine
|
||||
if (state.currentReader.currentSpineIndex > 0) {
|
||||
state.currentReader.currentSpineIndex--;
|
||||
renderSpineItem();
|
||||
}
|
||||
}
|
||||
} else if (state.currentReader.type === "pdf") {
|
||||
if (state.currentReader.currentPage > 1) {
|
||||
|
||||
Reference in New Issue
Block a user