| # Add Shift+Scroll Zoom to Map Georectification App |
|
|
| ## Context |
| The Gradio app displays map images via `gr.Image` components but has no zoom capability. For precise GCP placement and coordinate querying, users need to zoom into the image. The simplest approach is injecting custom JavaScript. |
|
|
| ## Approach |
| Inject a JS snippet via the `js` parameter on `gr.Blocks()` that: |
| 1. Listens for `wheel` events on image containers (`.image-container img`) |
| 2. When `shiftKey` is held, prevents default scroll and adjusts a CSS `transform: scale()` + `transform-origin` on the image |
| 3. Supports zoom in/out with shift+scroll, clamped to a reasonable range (e.g. 1x–10x) |
| 4. Sets `overflow: hidden` on the image container so zoomed content is clipped properly |
|
|
| ## File to modify |
| - `/home/inverse/workspace/images/app.py` — single change |
|
|
| ## Change detail |
| 1. Define a `ZOOM_JS` string constant containing the JavaScript |
| 2. Pass `js=ZOOM_JS` to `gr.Blocks(title="Map Georectification", js=ZOOM_JS)` |
|
|
| The JS will: |
| - Use event delegation on `document` for `wheel` events |
| - Find the closest `.image-container` ancestor |
| - Track zoom level per element (stored as a data attribute) |
| - Apply `transform: scale(zoom)` with `transform-origin` at the cursor position |
| - Clamp zoom between 1x and 10x |
| - Reset to 1x on double-click (bonus) |
|
|
| ## Verification |
| - `uv run app.py` and open in browser |
| - Hold Shift and scroll over either image — it should zoom in/out |
| - Release Shift — normal page scroll resumes |
| - Image click events (GCP placement, coordinate query) should still work at any zoom level |
|
|