cgeorgiaw HF Staff commited on
Commit
26442a2
·
verified ·
1 Parent(s): d83f404

Apply zoom styles only when actively zoomed (preserves Gradio centering)

Browse files
Files changed (1) hide show
  1. app.py +24 -13
app.py CHANGED
@@ -300,24 +300,31 @@ def choose(side: str, session: dict):
300
  # Shift+wheel zoom, drag-pan when zoomed, dbl-click reset. Pan is clamped so
301
  # the image always fills its container; max 4x. Resets on src change.
302
  ZOOM_HEAD = """
303
- <style>
304
- .zoomable img {
305
- transform-origin: 0 0;
306
- transition: transform 0.05s ease-out;
307
- will-change: transform;
308
- }
309
- </style>
310
  <script>
311
  (function () {
312
  const MAX_SCALE = 10;
313
  function bind(img) {
314
  if (img.__zoomBound) return;
315
  img.__zoomBound = true;
316
- // Clip on the immediate parent only; broader CSS selectors collapse
317
- // Gradio's column layout for the A/B images.
318
- if (img.parentElement) img.parentElement.style.overflow = 'hidden';
319
  let scale = 1, tx = 0, ty = 0;
320
  let dragging = false, lastX = 0, lastY = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  function clamp() {
322
  const w = img.clientWidth || img.naturalWidth || 1;
323
  const h = img.clientHeight || img.naturalHeight || 1;
@@ -325,10 +332,14 @@ ZOOM_HEAD = """
325
  tx = Math.min(0, Math.max(minX, tx));
326
  ty = Math.min(0, Math.max(minY, ty));
327
  }
328
- const apply = () => { clamp(); img.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`; };
329
- const reset = () => { scale = 1; tx = 0; ty = 0; img.style.transform = ''; };
 
 
 
 
330
  img.addEventListener('wheel', (e) => {
331
- if (!e.shiftKey) return; // plain scroll = page scroll
332
  e.preventDefault();
333
  const factor = e.deltaY < 0 ? 1.15 : 1 / 1.15;
334
  const ns = Math.min(MAX_SCALE, Math.max(1, scale * factor));
 
300
  # Shift+wheel zoom, drag-pan when zoomed, dbl-click reset. Pan is clamped so
301
  # the image always fills its container; max 4x. Resets on src change.
302
  ZOOM_HEAD = """
 
 
 
 
 
 
 
303
  <script>
304
  (function () {
305
  const MAX_SCALE = 10;
306
  function bind(img) {
307
  if (img.__zoomBound) return;
308
  img.__zoomBound = true;
 
 
 
309
  let scale = 1, tx = 0, ty = 0;
310
  let dragging = false, lastX = 0, lastY = 0;
311
+ const parent = img.parentElement;
312
+
313
+ // Apply zoom styles only while actively zoomed; restoring them on reset
314
+ // lets Gradio's own positioning/centering work at scale=1.
315
+ function setZoomStyles(on) {
316
+ if (!parent) return;
317
+ if (on) {
318
+ parent.style.overflow = 'hidden';
319
+ img.style.transformOrigin = '0 0';
320
+ img.style.willChange = 'transform';
321
+ } else {
322
+ parent.style.overflow = '';
323
+ img.style.transformOrigin = '';
324
+ img.style.willChange = '';
325
+ img.style.transform = '';
326
+ }
327
+ }
328
  function clamp() {
329
  const w = img.clientWidth || img.naturalWidth || 1;
330
  const h = img.clientHeight || img.naturalHeight || 1;
 
332
  tx = Math.min(0, Math.max(minX, tx));
333
  ty = Math.min(0, Math.max(minY, ty));
334
  }
335
+ const apply = () => {
336
+ setZoomStyles(true);
337
+ clamp();
338
+ img.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;
339
+ };
340
+ const reset = () => { scale = 1; tx = 0; ty = 0; setZoomStyles(false); };
341
  img.addEventListener('wheel', (e) => {
342
+ if (!e.shiftKey) return;
343
  e.preventDefault();
344
  const factor = e.deltaY < 0 ? 1.15 : 1 / 1.15;
345
  const ns = Math.min(MAX_SCALE, Math.max(1, scale * factor));