Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ coverage*/
.env

.vscode

# Local Netlify folder
.netlify
2 changes: 1 addition & 1 deletion .testcaferc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module.exports = {
appCommand: "npm run serve",
browsers: [
"chrome:headless",
"chrome:headless --disable-web-security --disable-features=VizDisplayCompositor --no-cache",
"firefox:headless",
],
src: ["tests/e2e/**/*test.js"]
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@
"build-js:watch": "npx webpack --mode=development --watch",
"build-css": "npx sass --no-source-map ./src/css/BookReader.scss ./BookReader/BookReader.css",
"build-css:watch": "npx sass --watch --no-source-map ./src/css/BookReader.scss ./BookReader/BookReader.css",
"clean": "rm -r BookReader/ || true",
"clean": "if exist BookReader rmdir /s /q BookReader",
"lint": "npx eslint src/ tests/ *.js *.cjs",
"lint:fix": "npx eslint --fix src/ tests/ *.js *.cjs",
"serve": "npx http-server . --port=8000",
"serve": "npx http-server . --port=8000 --cors --no-cache",
"serve-live": "npx live-server . --cors --port=8000 --watch=index.html,BookReader,BookReaderDemo",
"serve-dev": "env NODE_ENV='development' npm run build-css && env NODE_ENV='development' npx concurrently --kill-others npm:serve-live npm:build-*:watch",
"test": "npx jest --coverage --colors",
Expand Down
80 changes: 71 additions & 9 deletions src/BookReader/Mode1UpLit.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { ModeCoordinateSpace } from './ModeCoordinateSpace.js';
/** @implements {SmoothZoomable} */
@customElement('br-mode-1up')
export class Mode1UpLit extends LitElement {
/** @type {'width' | 'height' | 'auto' | 'none'} */
autoFit = 'auto';
/****************************************/
/************** PROPERTIES **************/
/****************************************/
Expand Down Expand Up @@ -125,22 +127,80 @@ export class Mode1UpLit extends LitElement {
* @param {PageIndex} index
*/
jumpToIndex(index, { smooth = false } = {}) {
if (smooth) {
this.style.scrollBehavior = 'smooth';
const currentScale = this.scale;

console.log(`🔍 SIMPLE JUMP: Going to page ${index}, scale: ${currentScale}`);

// Make sure we have page positions
if (!this.pageTops[index]) {
this.pageTops = this.computePageTops(this.pages, this.SPACING_IN);
}
this.scrollTop = this.coordSpace.worldUnitsToVisiblePixels(this.pageTops[index] - this.SPACING_IN / 2);
// TODO: Also h center?
if (smooth) {
setTimeout(() => this.style.scrollBehavior = '', 100);

// For HIGH ZOOM (> 2.0): Go to center of target page
if (currentScale > 2.0) {
console.log(`🎯 HIGH ZOOM: Centering page ${index}`);

const targetPage = this.pages.find(p => p.index === index);
if (!targetPage) {
console.error(`❌ Page ${index} not found!`);
return;
}

// Calculate center of the TARGET page
const pageTop = this.pageTops[index];
const pageHeight = targetPage.heightInches;
const pageCenterY = pageTop + (pageHeight / 2);

// Calculate scroll position to center the page
const viewportHeight = this.coordSpace.visiblePixelsToWorldUnits(this.htmlDimensionsCacher.clientHeight);
const targetScrollTop = this.coordSpace.worldUnitsToVisiblePixels(pageCenterY - (viewportHeight / 2));

console.log(`📍 Scrolling to center: ${targetScrollTop}`);

// Navigate to center
this.scrollTop = Math.max(0, targetScrollTop);

} else {
// NORMAL ZOOM: Go to top of page
console.log(`📄 NORMAL ZOOM: Going to top of page ${index}`);

const targetScrollTop = this.coordSpace.worldUnitsToVisiblePixels(this.pageTops[index] - this.SPACING_IN / 2);
this.scrollTop = targetScrollTop;
}

// Force update after any navigation
setTimeout(() => {
this.updateVisibleRegion();
this.throttledUpdateRenderedPages();
console.log(`✅ Navigation to page ${index} COMPLETE`);
}, 100);
}

zoomIn() {
this.scale *= this.ZOOM_FACTOR;
const newScale = this.scale * 1.1; // Same zoom factor as two-page mode (NO LIMIT)
if (newScale !== this.scale) {
this.scale = newScale;
this.requestUpdate();
// Force update visible region to prevent black screen issues
setTimeout(() => {
this.updateVisibleRegion();
this.throttledUpdateRenderedPages();
}, 50);
}
}

zoomOut() {
this.scale *= 1 / this.ZOOM_FACTOR;
const newScale = this.scale / 1.1; // Same zoom factor as two-page mode
if (newScale !== this.scale) {
this.scale = newScale;
this.requestUpdate();
// Force update visible region to prevent black screen issues
setTimeout(() => {
this.updateVisibleRegion();
this.throttledUpdateRenderedPages();
// Ensure proper centering after zoom - removed scrollIntoView as it causes navigation issues
}, 50);
}
}

/********************************************/
Expand Down Expand Up @@ -196,7 +256,8 @@ export class Mode1UpLit extends LitElement {
// unclear why this is ever really happening
this.br.displayedIndices = this.visiblePages.map(p => p.index);
this.br.updateFirstIndex(this.br.displayedIndices[0]);
this.br._components.navbar.updateNavIndexThrottled();
// Trigger an event to update the navbar instead of accessing private property
this.br.trigger('pageVisible', { pageContainerEl: null });
}
}
if (changedProps.has('scale')) {
Expand Down Expand Up @@ -390,4 +451,5 @@ export class Mode1UpLit extends LitElement {
this.removeEventListener("scroll", this.updateVisibleRegion);
this.scrollClassAdder.detach();
}

}
Loading