generated from john/python-template
reworked zooming
This commit is contained in:
@@ -60,16 +60,16 @@ def _register_panzoom_assets() -> None:
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.document-panzoom-media {
|
||||
width: auto;
|
||||
height: auto;
|
||||
display: block;
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
@@ -99,79 +99,76 @@ def _attach_panzoom(host_id: str) -> None:
|
||||
const media = host.querySelector('[data-panzoom-media]');
|
||||
if (!target) return;
|
||||
|
||||
const cleanup = () => {{
|
||||
const existing = window.__transcriptionPanzoom[{host_id!r}];
|
||||
if (existing?.resizeObserver) existing.resizeObserver.disconnect();
|
||||
if (existing?.wheelHandler) host.removeEventListener('wheel', existing.wheelHandler);
|
||||
if (existing?.instance) existing.instance.destroy();
|
||||
}};
|
||||
|
||||
const computeFitScale = () => {{
|
||||
const hostRect = host.getBoundingClientRect();
|
||||
if (hostRect.width <= 0 || hostRect.height <= 0) return 1;
|
||||
|
||||
if (media && media.tagName === 'IMG') {{
|
||||
if (media.naturalWidth <= 0 || media.naturalHeight <= 0) return 1;
|
||||
return Math.min(
|
||||
hostRect.width / media.naturalWidth,
|
||||
hostRect.height / media.naturalHeight
|
||||
);
|
||||
}}
|
||||
|
||||
if (target.tagName === 'IFRAME') {{
|
||||
const targetRect = target.getBoundingClientRect();
|
||||
if (targetRect.width <= 0 || targetRect.height <= 0) return 1;
|
||||
return hostRect.height / targetRect.height;
|
||||
}}
|
||||
|
||||
if (hostRect.width <= 0 || hostRect.height <= 0) return null;
|
||||
return 1;
|
||||
}};
|
||||
|
||||
const initPanzoom = () => {{
|
||||
if (window.__transcriptionPanzoom[{host_id!r}]) {{
|
||||
window.__transcriptionPanzoom[{host_id!r}].destroy();
|
||||
}}
|
||||
const buildInstance = () => {{
|
||||
cleanup();
|
||||
|
||||
if (host.__transcriptionWheelHandler) {{
|
||||
host.removeEventListener('wheel', host.__transcriptionWheelHandler);
|
||||
host.__transcriptionWheelHandler = null;
|
||||
}}
|
||||
const fitScale = computeFitScale();
|
||||
if (fitScale === null) return false;
|
||||
|
||||
let fitScale = computeFitScale();
|
||||
|
||||
if (!Number.isFinite(fitScale) || fitScale <= 0) {{
|
||||
fitScale = 1;
|
||||
}}
|
||||
|
||||
const startScale = fitScale;
|
||||
const minScale = 0.01;
|
||||
const minScale = Math.min(fitScale, 0.01);
|
||||
const instance = Panzoom(target, {{
|
||||
maxScale: 32,
|
||||
startX: 0,
|
||||
startY: 0,
|
||||
startScale: fitScale,
|
||||
minScale: minScale,
|
||||
startScale: startScale,
|
||||
step: 0.18,
|
||||
contain: 'inside',
|
||||
roundPixels: true,
|
||||
maxScale: 256,
|
||||
step: 0.2,
|
||||
roundPixels: false,
|
||||
panOnlyWhenZoomed: true,
|
||||
overflow: 'hidden',
|
||||
}});
|
||||
|
||||
window.__transcriptionPanzoom[{host_id!r}] = instance;
|
||||
const wheelHandler = (event) => instance.zoomWithWheel(event);
|
||||
host.addEventListener('wheel', wheelHandler, {{ passive: false }});
|
||||
|
||||
requestAnimationFrame(() => {{
|
||||
instance.reset({{ animate: false, force: true }});
|
||||
instance.setOptions({{ contain: undefined }});
|
||||
instance.reset({{ animate: false }});
|
||||
}});
|
||||
|
||||
const wheelHandler = (event) => instance.zoomWithWheel(event);
|
||||
host.__transcriptionWheelHandler = wheelHandler;
|
||||
host.addEventListener('wheel', wheelHandler, {{ passive: false }});
|
||||
const resizeObserver = new ResizeObserver(() => {{
|
||||
const nextFitScale = computeFitScale();
|
||||
if (nextFitScale === null) return;
|
||||
instance.setOptions({{
|
||||
startScale: nextFitScale,
|
||||
minScale: Math.min(nextFitScale, 0.01),
|
||||
}});
|
||||
instance.reset({{ animate: false }});
|
||||
}});
|
||||
resizeObserver.observe(host);
|
||||
|
||||
window.__transcriptionPanzoom[{host_id!r}] = {{
|
||||
instance,
|
||||
wheelHandler,
|
||||
resizeObserver,
|
||||
}};
|
||||
return true;
|
||||
}};
|
||||
|
||||
const initWhenReady = (retries = 15) => {{
|
||||
if (buildInstance()) return;
|
||||
if (retries <= 0) return;
|
||||
requestAnimationFrame(() => initWhenReady(retries - 1));
|
||||
}};
|
||||
|
||||
if (media && media.tagName === 'IMG' && !media.complete) {{
|
||||
media.addEventListener('load', initPanzoom, {{ once: true }});
|
||||
media.addEventListener('load', () => initWhenReady(), {{ once: true }});
|
||||
return;
|
||||
}}
|
||||
|
||||
if ((media && media.tagName === 'IMG' && (host.clientWidth <= 0 || host.clientHeight <= 0)) ||
|
||||
(target.tagName === 'IFRAME' && (host.clientWidth <= 0 || host.clientHeight <= 0))) {{
|
||||
requestAnimationFrame(initPanzoom);
|
||||
return;
|
||||
}}
|
||||
|
||||
initPanzoom();
|
||||
initWhenReady();
|
||||
}})();
|
||||
"""
|
||||
)
|
||||
@@ -186,10 +183,11 @@ def render_document_panzoom(*, document: Document, height: str = "640px") -> Non
|
||||
document_kind = _document_kind(document)
|
||||
|
||||
with ui.card().classes("w-full q-pa-md"):
|
||||
with ui.column().classes("q-gutter-none"):
|
||||
with ui.row().classes("w-full items-center justify-between q-gutter-sm"):
|
||||
ui.label("Document preview").classes("text-subtitle1 text-weight-medium")
|
||||
ui.label(document.filename).classes("text-caption text-grey-4")
|
||||
with ui.row().classes("w-full items-center justify-between no-wrap"):
|
||||
ui.label("Document preview").classes("text-subtitle1 text-weight-medium")
|
||||
ui.label(document.filename).classes("text-caption text-grey-4 ellipsis").style(
|
||||
"max-width: 60%; text-align: right;"
|
||||
)
|
||||
|
||||
with (
|
||||
ui.element("div")
|
||||
|
||||
Reference in New Issue
Block a user