Zoom mode

This commit is contained in:
Simon Martens
2025-09-23 05:15:46 +02:00
parent fcbd9f9e5c
commit 5bd0e51b76
3 changed files with 107 additions and 65 deletions

View File

@@ -1,4 +1,4 @@
class T extends HTMLElement { class I extends HTMLElement {
constructor() { constructor() {
super(), this.scrollHandler = null, this.scrollTimeout = null, this.clickHandlers = [], this.manualNavigation = !1; super(), this.scrollHandler = null, this.scrollTimeout = null, this.clickHandlers = [], this.manualNavigation = !1;
} }
@@ -67,18 +67,18 @@ class T extends HTMLElement {
const o = n.getAttribute("id"), r = n.querySelector(".akteur-werke-section"), a = n.querySelector(".akteur-beitraege-section"); const o = n.getAttribute("id"), r = n.querySelector(".akteur-werke-section"), a = n.querySelector(".akteur-beitraege-section");
let l = !1; let l = !1;
if (r) { if (r) {
const c = r.getBoundingClientRect(), d = c.top < window.innerHeight, g = c.bottom > 0; const c = r.getBoundingClientRect(), d = c.top < window.innerHeight, u = c.bottom > 0;
d && g && (l = !0); d && u && (l = !0);
} }
if (a && !l) { if (a && !l) {
const c = a.getBoundingClientRect(), d = c.top < window.innerHeight, g = c.bottom > 0; const c = a.getBoundingClientRect(), d = c.top < window.innerHeight, u = c.bottom > 0;
d && g && (l = !0); d && u && (l = !0);
} }
if (!r && !a) { if (!r && !a) {
const c = n.querySelector("div:first-child"); const c = n.querySelector("div:first-child");
if (c) { if (c) {
const d = c.getBoundingClientRect(), g = d.top >= 0, u = d.bottom <= window.innerHeight; const d = c.getBoundingClientRect(), u = d.top >= 0, g = d.bottom <= window.innerHeight;
g && u && (l = !0); u && g && (l = !0);
} }
} }
l && e.push(o); l && e.push(o);
@@ -95,8 +95,8 @@ class T extends HTMLElement {
const n = document.getElementById("scrollspy-nav"), o = n.getBoundingClientRect(); const n = document.getElementById("scrollspy-nav"), o = n.getBoundingClientRect();
let r = 1 / 0, a = -1 / 0; let r = 1 / 0, a = -1 / 0;
i.forEach((c) => { i.forEach((c) => {
const d = c.getBoundingClientRect(), g = d.top - o.top + n.scrollTop, u = g + d.height; const d = c.getBoundingClientRect(), u = d.top - o.top + n.scrollTop, g = u + d.height;
r = Math.min(r, g), a = Math.max(a, u); r = Math.min(r, u), a = Math.max(a, g);
}); });
let l = a - r; let l = a - r;
t.style.top = `${r}px`, t.style.height = `${l}px`, t.style.opacity = "1", setTimeout(() => this.ensureMarkerVisibility(), 100); t.style.top = `${r}px`, t.style.height = `${l}px`, t.style.opacity = "1", setTimeout(() => this.ensureMarkerVisibility(), 100);
@@ -134,8 +134,8 @@ class T extends HTMLElement {
document.documentElement.offsetHeight document.documentElement.offsetHeight
), o = window.innerHeight, r = n - o, a = r > 0 ? window.scrollY / r : 0, l = i.clientHeight, d = i.scrollHeight - l; ), o = window.innerHeight, r = n - o, a = r > 0 ? window.scrollY / r : 0, l = i.clientHeight, d = i.scrollHeight - l;
if (d > 0) { if (d > 0) {
const g = a * d, u = t.getBoundingClientRect(), p = i.getBoundingClientRect(), f = u.top - p.top + i.scrollTop, m = l / 2, E = f - m, y = 0.7, H = y * g + (1 - y) * E, x = Math.max(0, Math.min(d, H)), I = i.scrollTop; const u = a * d, g = t.getBoundingClientRect(), p = i.getBoundingClientRect(), f = g.top - p.top + i.scrollTop, m = l / 2, E = f - m, y = 0.7, H = y * u + (1 - y) * E, x = Math.max(0, Math.min(d, H)), T = i.scrollTop;
Math.abs(x - I) > 10 && i.scrollTo({ Math.abs(x - T) > 10 && i.scrollTo({
top: x, top: x,
behavior: "smooth" behavior: "smooth"
}); });
@@ -155,10 +155,10 @@ class T extends HTMLElement {
e && (e.style.opacity = "0", e.style.height = "0"), this.sections = null, this.navLinks = null, this.clickHandlers = [], this.manualNavigation = !1; e && (e.style.opacity = "0", e.style.height = "0"), this.sections = null, this.navLinks = null, this.clickHandlers = [], this.manualNavigation = !1;
} }
} }
customElements.define("akteure-scrollspy", T); customElements.define("akteure-scrollspy", I);
class A extends HTMLElement { class A extends HTMLElement {
constructor() { constructor() {
super(), this.resizeObserver = null, this.zoomLevel = 1, this.minZoom = 1, this.maxZoom = 4, this.panX = 0, this.panY = 0, this.isDragging = !1, this.lastMouseX = 0, this.lastMouseY = 0; super(), this.resizeObserver = null, this.zoomLevel = 1, this.minZoom = 1, this.maxZoom = 4, this.panX = 0, this.panY = 0, this.isDragging = !1, this.lastMouseX = 0, this.lastMouseY = 0, this.clickStartTime = null, this.clickStartX = null, this.clickStartY = null;
} }
// Dynamically detect sidebar width in pixels // Dynamically detect sidebar width in pixels
detectSidebarWidth() { detectSidebarWidth() {
@@ -275,9 +275,9 @@ class A extends HTMLElement {
id="single-page-image" id="single-page-image"
src="" src=""
alt="" alt=""
class="rounded-lg shadow-2xl cursor-zoom-in select-none" class="rounded-lg shadow-2xl cursor-zoom-out select-none"
style="transform: scale(1) translate3d(0px, 0px, 0); transform-origin: center center; will-change: transform;" style="transform: scale(1) translate3d(0px, 0px, 0); transform-origin: center center; will-change: transform;"
title="Zoom mit Strg + Mausrad oder +/- Tasten" title="Klicken zum Schließen oder Zoom mit Strg + Mausrad / +/- Tasten"
draggable="false" draggable="false"
/> />
</div> </div>
@@ -302,23 +302,23 @@ class A extends HTMLElement {
} }
} }
show(e, i, t, n = !1, o = 0, r = null, a = null, l = null) { show(e, i, t, n = !1, o = 0, r = null, a = null, l = null) {
const c = this.querySelector("#single-page-image"), d = this.querySelector("#page-number"), g = this.querySelector("#page-icon"); const c = this.querySelector("#single-page-image"), d = this.querySelector("#page-number"), u = this.querySelector("#page-icon");
this.querySelector("#page-indicator"), c.src = e, c.alt = i, this.currentPageNumber = t, this.currentIsBeilage = n, this.currentPartNumber = r; this.querySelector("#page-indicator"), c.src = e, c.alt = i, this.currentPageNumber = t, this.currentIsBeilage = n, this.currentPartNumber = r;
let u; let g;
if (l) if (l)
u = l; g = l;
else { else {
const f = this.getIssueContext(t); const f = this.getIssueContext(t);
u = f ? `${f}, ${t}` : `${t}`; g = f ? `${f}, ${t}` : `${t}`;
} }
if (d.innerHTML = u, o && t === o) { if (d.innerHTML = g, o && t === o) {
d.style.position = "relative"; d.style.position = "relative";
const f = d.querySelector(".target-page-dot"); const f = d.querySelector(".target-page-dot");
f && f.remove(); f && f.remove();
const m = document.createElement("span"); const m = document.createElement("span");
m.className = "target-page-dot absolute -top-1 -right-1 w-3 h-3 bg-red-500 rounded-full z-10", m.title = "verlinkte Seite", d.appendChild(m); m.className = "target-page-dot absolute -top-1 -right-1 w-3 h-3 bg-red-500 rounded-full z-10", m.title = "verlinkte Seite", d.appendChild(m);
} }
a ? a === "part-number" && r !== null ? g.innerHTML = `<span class="part-number bg-slate-100 text-slate-800 font-bold px-1.5 py-0.5 rounded border border-slate-400 flex items-center justify-center">${r}. Teil</span>` : g.innerHTML = this.generateIconFromType(a) : g.innerHTML = this.generateFallbackIcon(t, n, r), this.updateNavigationButtons(), this.style.display = "block", this.setAttribute("active", "true"), this.resetZoom(); a ? a === "part-number" && r !== null ? u.innerHTML = `<span class="part-number bg-slate-100 text-slate-800 font-bold px-1.5 py-0.5 rounded border border-slate-400 flex items-center justify-center">${r}. Teil</span>` : u.innerHTML = this.generateIconFromType(a) : u.innerHTML = this.generateFallbackIcon(t, n, r), this.updateNavigationButtons(), this.style.display = "block", this.setAttribute("active", "true"), this.resetZoom();
const p = this.querySelector(".flex-1.overflow-auto"); const p = this.querySelector(".flex-1.overflow-auto");
p && (p.scrollTop = 0), document.body.style.overflow = "hidden", document.dispatchEvent(new CustomEvent("singlepageviewer:opened", { p && (p.scrollTop = 0), document.body.style.overflow = "hidden", document.dispatchEvent(new CustomEvent("singlepageviewer:opened", {
detail: { pageNumber: this.currentPageNumber, isBeilage: this.currentIsBeilage } detail: { pageNumber: this.currentPageNumber, isBeilage: this.currentIsBeilage }
@@ -401,7 +401,7 @@ class A extends HTMLElement {
} }
} }
}, this.mouseDownHandler = (t) => { }, this.mouseDownHandler = (t) => {
this.style.display === "none" || this.zoomLevel <= 1 || t.button === 0 && (t.preventDefault(), this.isDragging = !0, this.lastMouseX = t.clientX, this.lastMouseY = t.clientY, this.updateCursor()); this.style.display !== "none" && t.button === 0 && (this.zoomLevel <= 1 ? (this.clickStartTime = Date.now(), this.clickStartX = t.clientX, this.clickStartY = t.clientY) : (t.preventDefault(), this.isDragging = !0, this.lastMouseX = t.clientX, this.lastMouseY = t.clientY, this.updateCursor()));
}, this.mouseMoveHandler = (t) => { }, this.mouseMoveHandler = (t) => {
if (this.style.display !== "none" && this.isDragging && this.zoomLevel > 1) { if (this.style.display !== "none" && this.isDragging && this.zoomLevel > 1) {
t.preventDefault(); t.preventDefault();
@@ -411,7 +411,14 @@ class A extends HTMLElement {
})); }));
} }
}, this.mouseUpHandler = (t) => { }, this.mouseUpHandler = (t) => {
this.isDragging && (this.isDragging = !1, this.updateCursor()); if (this.isDragging)
this.isDragging = !1, this.updateCursor();
else if (this.zoomLevel <= 1 && this.clickStartTime) {
const n = Date.now() - this.clickStartTime, o = Math.sqrt(
Math.pow(t.clientX - this.clickStartX, 2) + Math.pow(t.clientY - this.clickStartY, 2)
);
n < 300 && o < 10 && this.close(), this.clickStartTime = null, this.clickStartX = null, this.clickStartY = null;
}
}, i.addEventListener("wheel", this.wheelHandler, { passive: !1 }), e.addEventListener("mousedown", this.mouseDownHandler), document.addEventListener("mousemove", this.mouseMoveHandler), document.addEventListener("mouseup", this.mouseUpHandler), e.addEventListener("contextmenu", (t) => t.preventDefault()); }, i.addEventListener("wheel", this.wheelHandler, { passive: !1 }), e.addEventListener("mousedown", this.mouseDownHandler), document.addEventListener("mousemove", this.mouseMoveHandler), document.addEventListener("mouseup", this.mouseUpHandler), e.addEventListener("contextmenu", (t) => t.preventDefault());
} }
// Zoom function // Zoom function
@@ -420,8 +427,8 @@ class A extends HTMLElement {
if (n === this.zoomLevel) return; if (n === this.zoomLevel) return;
const r = this.querySelector("#single-page-image").getBoundingClientRect(); const r = this.querySelector("#single-page-image").getBoundingClientRect();
if (i !== null && t !== null) { if (i !== null && t !== null) {
const a = r.width / 2, l = r.height / 2, c = i - a, d = t - l, g = n / this.zoomLevel; const a = r.width / 2, l = r.height / 2, c = i - a, d = t - l, u = n / this.zoomLevel;
this.panX = this.panX * g - c * (g - 1), this.panY = this.panY * g - d * (g - 1); this.panX = this.panX * u - c * (u - 1), this.panY = this.panY * u - d * (u - 1);
} else { } else {
const a = n / this.zoomLevel; const a = n / this.zoomLevel;
this.panX *= a, this.panY *= a; this.panX *= a, this.panY *= a;
@@ -436,7 +443,7 @@ class A extends HTMLElement {
// Update cursor based on zoom state // Update cursor based on zoom state
updateCursor() { updateCursor() {
const e = this.querySelector("#single-page-image"); const e = this.querySelector("#single-page-image");
this.isDragging ? e.style.cursor = "grabbing" : this.zoomLevel > 1 ? this.zoomLevel >= this.maxZoom ? e.style.cursor = "zoom-out" : e.style.cursor = "grab" : e.style.cursor = "zoom-in"; this.isDragging ? e.style.cursor = "grabbing" : this.zoomLevel > 1 ? this.zoomLevel >= this.maxZoom ? e.style.cursor = "zoom-out" : e.style.cursor = "grab" : e.style.cursor = "zoom-out";
} }
// Update zoom level display and reset button // Update zoom level display and reset button
updateZoomDisplay() { updateZoomDisplay() {
@@ -445,7 +452,7 @@ class A extends HTMLElement {
} }
// Reset zoom state when showing new image // Reset zoom state when showing new image
resetZoom() { resetZoom() {
this.zoomLevel = 1, this.panX = 0, this.panY = 0, this.isDragging = !1, this.updateImageTransform(), this.updateCursor(), this.updateZoomDisplay(); this.zoomLevel = 1, this.panX = 0, this.panY = 0, this.isDragging = !1, this.clickStartTime = null, this.clickStartX = null, this.clickStartY = null, this.updateImageTransform(), this.updateCursor(), this.updateZoomDisplay();
} }
// Share current page // Share current page
shareCurrentPage() { shareCurrentPage() {
@@ -578,12 +585,12 @@ class A extends HTMLElement {
if (r) { if (r) {
const c = r.querySelector(".page-indicator"); const c = r.querySelector(".page-indicator");
if (c) { if (c) {
const d = c.textContent.trim(), g = d.match(/(\d{1,2}\.\d{1,2}\.\d{4}\s+Nr\.\s+\d+)/); const d = c.textContent.trim(), u = d.match(/(\d{1,2}\.\d{1,2}\.\d{4}\s+Nr\.\s+\d+)/);
if (g)
return g[1];
const u = d.match(/(\d{4})\s+Nr\.\s+(\d+)/);
if (u) if (u)
return `${u[1]} Nr. ${u[2]}`; return u[1];
const g = d.match(/(\d{4})\s+Nr\.\s+(\d+)/);
if (g)
return `${g[1]} Nr. ${g[2]}`;
} }
} }
const l = document.title.match(/(\d{4}).*Nr\.\s*(\d+)/); const l = document.title.match(/(\d{4}).*Nr\.\s*(\d+)/);
@@ -745,25 +752,25 @@ customElements.define("inhaltsverzeichnis-scrollspy", q);
window.currentPageContainers = window.currentPageContainers || []; window.currentPageContainers = window.currentPageContainers || [];
window.currentActiveIndex = window.currentActiveIndex || 0; window.currentActiveIndex = window.currentActiveIndex || 0;
window.pageObserver = window.pageObserver || null; window.pageObserver = window.pageObserver || null;
function N(s, e, i, t = null) { function M(s, e, i, t = null) {
let n = document.querySelector("single-page-viewer"); let n = document.querySelector("single-page-viewer");
n || (n = document.createElement("single-page-viewer"), document.body.appendChild(n)); n || (n = document.createElement("single-page-viewer"), document.body.appendChild(n));
const o = s.closest('[data-beilage="true"]') !== null, r = window.templateData && window.templateData.targetPage ? window.templateData.targetPage : 0, a = s.closest(".newspaper-page-container, .piece-page-container"); const o = s.closest('[data-beilage="true"]') !== null, r = window.templateData && window.templateData.targetPage ? window.templateData.targetPage : 0, a = s.closest(".newspaper-page-container, .piece-page-container");
let l = null, c = null; let l = null, c = null;
if (a) { if (a) {
l = a.getAttribute("data-page-icon-type"), a.querySelector(".part-number") && (l = "part-number"); l = a.getAttribute("data-page-icon-type"), a.querySelector(".part-number") && (l = "part-number");
const g = a.querySelector(".page-indicator"); const u = a.querySelector(".page-indicator");
if (g) { if (u) {
const u = g.cloneNode(!0); const g = u.cloneNode(!0);
u.querySelectorAll("i").forEach((m) => m.remove()), u.querySelectorAll('[class*="target-page-dot"], .target-page-indicator').forEach((m) => m.remove()), c = u.textContent.trim(); g.querySelectorAll("i").forEach((m) => m.remove()), g.querySelectorAll('[class*="target-page-dot"], .target-page-indicator').forEach((m) => m.remove()), c = g.textContent.trim();
} }
} }
n.show(s.src, s.alt, e, o, r, t, l, c); n.show(s.src, s.alt, e, o, r, t, l, c);
} }
function k() { function C() {
document.getElementById("pageModal").classList.add("hidden"); document.getElementById("pageModal").classList.add("hidden");
} }
function M() { function N() {
if (window.pageObserver && (window.pageObserver.disconnect(), window.pageObserver = null), window.currentPageContainers = Array.from(document.querySelectorAll(".newspaper-page-container")), window.currentActiveIndex = 0, b(), document.querySelector(".newspaper-page-container")) { if (window.pageObserver && (window.pageObserver.disconnect(), window.pageObserver = null), window.currentPageContainers = Array.from(document.querySelectorAll(".newspaper-page-container")), window.currentActiveIndex = 0, b(), document.querySelector(".newspaper-page-container")) {
let e = /* @__PURE__ */ new Set(); let e = /* @__PURE__ */ new Set();
window.pageObserver = new IntersectionObserver( window.pageObserver = new IntersectionObserver(
@@ -1008,12 +1015,12 @@ function O(s, e) {
} }
} }
function P() { function P() {
M(), window.addEventListener("scroll", function() { N(), window.addEventListener("scroll", function() {
clearTimeout(window.scrollTimeout), window.scrollTimeout = setTimeout(() => { clearTimeout(window.scrollTimeout), window.scrollTimeout = setTimeout(() => {
b(); b();
}, 50); }, 50);
}), document.addEventListener("keydown", function(s) { }), document.addEventListener("keydown", function(s) {
s.key === "Escape" && k(); s.key === "Escape" && C();
}); });
} }
function w() { function w() {
@@ -1026,14 +1033,14 @@ function w() {
else { else {
const o = s.match(/^\/(\d{4})\/(\d+)(?:\/(\d+))?$/), r = t.match(/^\/(\d{4})\/(\d+)$/); const o = s.match(/^\/(\d{4})\/(\d+)(?:\/(\d+))?$/), r = t.match(/^\/(\d{4})\/(\d+)$/);
if (o && r) { if (o && r) {
const [, a, l, c] = o, [, d, g] = r; const [, a, l, c] = o, [, d, u] = r;
a === d && l === g && (n = !0); a === d && l === u && (n = !0);
} }
} }
n ? (i.classList.add("text-red-700", "pointer-events-none"), i.setAttribute("aria-current", "page")) : (i.classList.remove("text-red-700", "pointer-events-none"), i.removeAttribute("aria-current")); n ? (i.classList.add("text-red-700", "pointer-events-none"), i.setAttribute("aria-current", "page")) : (i.classList.remove("text-red-700", "pointer-events-none"), i.removeAttribute("aria-current"));
}); });
} }
function C() { function k() {
const s = window.location.pathname, e = document.body; const s = window.location.pathname, e = document.body;
e.classList.remove( e.classList.remove(
"page-akteure", "page-akteure",
@@ -1059,8 +1066,8 @@ function Y() {
} }
} }
} }
window.enlargePage = N; window.enlargePage = M;
window.closeModal = k; window.closeModal = C;
window.scrollToPreviousPage = z; window.scrollToPreviousPage = z;
window.scrollToNextPage = $; window.scrollToNextPage = $;
window.scrollToBeilage = V; window.scrollToBeilage = V;
@@ -1068,10 +1075,10 @@ window.shareCurrentPage = R;
window.generateCitation = D; window.generateCitation = D;
window.copyPagePermalink = Z; window.copyPagePermalink = Z;
window.generatePageCitation = O; window.generatePageCitation = O;
function K() { function F() {
C(), w(), document.querySelector(".newspaper-page-container") && P(); k(), w(), document.querySelector(".newspaper-page-container") && P();
let s = function(i) { let s = function(i) {
C(), w(), Y(), setTimeout(() => { k(), w(), Y(), setTimeout(() => {
document.querySelector(".newspaper-page-container") && P(); document.querySelector(".newspaper-page-container") && P();
}, 50); }, 50);
}, e = function(i) { }, e = function(i) {
@@ -1079,5 +1086,5 @@ function K() {
document.body.addEventListener("htmx:afterSettle", s), document.body.addEventListener("htmx:afterSettle", w), document.body.addEventListener("htmx:beforeRequest", e); document.body.addEventListener("htmx:afterSettle", s), document.body.addEventListener("htmx:afterSettle", w), document.body.addEventListener("htmx:beforeRequest", e);
} }
export { export {
K as setup F as setup
}; };

File diff suppressed because one or more lines are too long

View File

@@ -18,6 +18,11 @@ export class SinglePageViewer extends HTMLElement {
this.isDragging = false; this.isDragging = false;
this.lastMouseX = 0; this.lastMouseX = 0;
this.lastMouseY = 0; this.lastMouseY = 0;
// Click tracking for close functionality
this.clickStartTime = null;
this.clickStartX = null;
this.clickStartY = null;
} }
// Dynamically detect sidebar width in pixels // Dynamically detect sidebar width in pixels
@@ -154,9 +159,9 @@ export class SinglePageViewer extends HTMLElement {
id="single-page-image" id="single-page-image"
src="" src=""
alt="" alt=""
class="rounded-lg shadow-2xl cursor-zoom-in select-none" class="rounded-lg shadow-2xl cursor-zoom-out select-none"
style="transform: scale(1) translate3d(0px, 0px, 0); transform-origin: center center; will-change: transform;" style="transform: scale(1) translate3d(0px, 0px, 0); transform-origin: center center; will-change: transform;"
title="Zoom mit Strg + Mausrad oder +/- Tasten" title="Klicken zum Schließen oder Zoom mit Strg + Mausrad / +/- Tasten"
draggable="false" draggable="false"
/> />
</div> </div>
@@ -470,20 +475,28 @@ export class SinglePageViewer extends HTMLElement {
} }
}; };
// Mouse down for pan start // Mouse down for pan start or close
this.mouseDownHandler = (event) => { this.mouseDownHandler = (event) => {
if (this.style.display === 'none' || this.zoomLevel <= 1.0) return; if (this.style.display === 'none') return;
// Only start dragging on left mouse button // Only handle left mouse button
if (event.button !== 0) return; if (event.button !== 0) return;
event.preventDefault(); if (this.zoomLevel <= 1.0) {
this.isDragging = true; // At 100% zoom - prepare for close on click
this.lastMouseX = event.clientX; this.clickStartTime = Date.now();
this.lastMouseY = event.clientY; this.clickStartX = event.clientX;
this.clickStartY = event.clientY;
} else {
// Above 100% zoom - prepare for pan
event.preventDefault();
this.isDragging = true;
this.lastMouseX = event.clientX;
this.lastMouseY = event.clientY;
// Update cursor // Update cursor
this.updateCursor(); this.updateCursor();
}
}; };
// Mouse move for panning // Mouse move for panning
@@ -512,11 +525,28 @@ export class SinglePageViewer extends HTMLElement {
} }
}; };
// Mouse up for pan end // Mouse up for pan end or close
this.mouseUpHandler = (event) => { this.mouseUpHandler = (event) => {
if (this.isDragging) { if (this.isDragging) {
this.isDragging = false; this.isDragging = false;
this.updateCursor(); this.updateCursor();
} else if (this.zoomLevel <= 1.0 && this.clickStartTime) {
// Check if this was a click (not a drag) at 100% zoom
const clickDuration = Date.now() - this.clickStartTime;
const clickDistance = Math.sqrt(
Math.pow(event.clientX - this.clickStartX, 2) +
Math.pow(event.clientY - this.clickStartY, 2)
);
// If it was a quick click with minimal movement, close the viewer
if (clickDuration < 300 && clickDistance < 10) {
this.close();
}
// Reset click tracking
this.clickStartTime = null;
this.clickStartX = null;
this.clickStartY = null;
} }
}; };
@@ -594,8 +624,8 @@ export class SinglePageViewer extends HTMLElement {
img.style.cursor = 'grab'; img.style.cursor = 'grab';
} }
} else { } else {
// At 100% zoom // At 100% zoom - zoom-out cursor indicates click to close
img.style.cursor = 'zoom-in'; img.style.cursor = 'zoom-out';
} }
} }
@@ -632,6 +662,11 @@ export class SinglePageViewer extends HTMLElement {
this.panY = 0; this.panY = 0;
this.isDragging = false; this.isDragging = false;
// Reset click tracking
this.clickStartTime = null;
this.clickStartX = null;
this.clickStartY = null;
this.updateImageTransform(); this.updateImageTransform();
this.updateCursor(); this.updateCursor();