mirror of
https://github.com/john-okeefe/foliate-js.git
synced 2026-09-09 11:29:14 -04:00
Add magnifier, interaction mode toggle, and zoom percentage display
Magnifier (fixed-layout.js): - Rewrite magnifier to use CSS background-image for comics (blob URLs from iframe img elements) and canvas drawImage for PDFs. Replaces broken iframe.cloneNode approach that created empty sandboxed clones. - Detect which iframe is under the cursor by checking bounding rects, so magnifier works on both left and right panes. - Forward mousemove events from iframe documents to handleMagnifierMove so the magnifier follows the cursor inside iframes. - Add background-repeat: no-repeat to lens styles. - Add zoomMagnifierEnabled getter for external state checks. Interaction mode toggle (PDF only): - Add 'interaction-mode' observed attribute with 'select'/'pan' values. - In select mode (default for PDFs): mouse events pass through for text selection; Shift+drag enables panning as a fallback. - In pan mode: drag-to-pan works as normal. - Comic books always use pan mode (no text to select). - Auto-detect PDF via #isPDF flag set in #showSpread from onZoom presence. - Add isPDF getter so reader.js can show/hide the toggle button. - Add toggle button in reader.html, hidden by default, shown for PDFs via the view 'load' event. - Escape key dismisses the magnifier. Zoom percentage display (reader.js): - Dispatch 'zoom' CustomEvent from #zoomByRatio with the new scale. - Listener in reader.js updates the percentage display on scroll zoom. Also includes minor formatting (line wrapping) in #goLeft/#goRight.
This commit is contained in:
@@ -221,6 +221,9 @@ class Reader {
|
||||
$("#magnifier-toggle").addEventListener("click", () => {
|
||||
console.log("[Reader Debug] 🔍 Magnifier toggle button clicked");
|
||||
const renderer = this.view.renderer;
|
||||
renderer.addEventListener("zoom", (e) => {
|
||||
$("#zoom-reset").textContent = `${Math.round(e.detail.scale * 100)}%`;
|
||||
});
|
||||
console.log(
|
||||
"[Reader Debug] Is FixedLayout?",
|
||||
renderer instanceof FixedLayout,
|
||||
@@ -232,6 +235,26 @@ class Reader {
|
||||
console.log("[Reader Debug] ❌ Not a FixedLayout renderer, ignoring");
|
||||
}
|
||||
});
|
||||
const modeToggle = $("#interaction-mode-toggle");
|
||||
modeToggle.addEventListener("click", () => {
|
||||
const renderer = this.view.renderer;
|
||||
if (!(renderer instanceof FixedLayout)) return;
|
||||
const current = renderer.getAttribute("interaction-mode") || "select";
|
||||
const next = current === "select" ? "pan" : "select";
|
||||
renderer.setAttribute("interaction-mode", next);
|
||||
modeToggle.title = next === "select" ? "Select Mode" : "Pan Mode";
|
||||
const svg = modeToggle.querySelector("svg");
|
||||
svg.innerHTML =
|
||||
next === "select"
|
||||
? '<path d="M 5 3 v 12 M 5 15 l -2 2 M 5 15 l 2 2 M 5 3 l 3 3" />'
|
||||
: '<path d="M 5 9 h 10 M 10 5 v 10" />';
|
||||
});
|
||||
this.view.addEventListener("load", () => {
|
||||
const renderer = this.view.renderer;
|
||||
if (renderer instanceof FixedLayout && renderer.isPDF) {
|
||||
modeToggle.style.display = "";
|
||||
}
|
||||
});
|
||||
console.log("[Reader Debug] ✅ Zoom control listeners configured");
|
||||
|
||||
const title = formatLanguageMap(book.metadata?.title) || "Untitled Book";
|
||||
@@ -328,6 +351,11 @@ class Reader {
|
||||
$("#zoom-reset").textContent = "100%";
|
||||
console.log("[Reader Debug] ✅ Keyboard zoom reset");
|
||||
}
|
||||
} else if (k === "Escape") {
|
||||
const renderer = this.view.renderer;
|
||||
if (renderer instanceof FixedLayout && renderer.zoomMagnifierEnabled) {
|
||||
renderer.toggleMagnifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
#onLoad({ detail: { doc } }) {
|
||||
|
||||
Reference in New Issue
Block a user