Skip to content

Commit 7ab8bf9

Browse files
committed
Implement zoom-out handling in _imgToCanvas2d and update documentation for consistency
1 parent ca95f27 commit 7ab8bf9

2 files changed

Lines changed: 18 additions & 4 deletions

File tree

anyplotlib/FIGURE_ESM.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,9 @@ st.share_axes
174174
| **`_imgFitRect(iw,ih,cw,ch)`** | **465** | **Returns `{x,y,w,h,s}` — the largest rect of aspect `iw:ih` centred in `cw×ch`. `s` = canvas-px per image-px. All 2-D coordinate functions derive from this.** |
175175
| `_buildLut32(st)` | 471 | Build 256-entry `Uint32Array` LUT from colormap + scale mode |
176176
| `_lutKey(st)` | 499 | String cache key (invalidates when colormap/range changes) |
177-
| `_imgToCanvas2d(ix,iy,st,pw,ph)` | 503 | Image pixel → canvas pixel using `_imgFitRect` + zoom/pan |
177+
| `_imgToCanvas2d(ix,iy,st,pw,ph)` | 503 | Image pixel → canvas pixel. **zoom≥1**: uses pan/crop formula. **zoom<1**: maps through the centred-shrink geometry (`dstX = x+(w-w·zoom)/2`) — must match `_blit2d` exactly. |
178178
| `_imgScale2d(st,pw,ph)` | 514 | Returns `_imgFitRect(…).s * zoom` — canvas-px per image-px at current zoom |
179-
| `_blit2d(bitmap,st,pw,ph,ctx)` | 518 | **Contain render**: clears canvas to `bgCanvas`, draws image inside fit-rect. zoom≥1 → crops + fills fit-rect; zoom<1 → shrinks fit-rect proportionally |
179+
| `_blit2d(bitmap,st,pw,ph,ctx)` | 518 | **Contain render**: clears canvas to `bgCanvas`, draws image inside fit-rect. zoom≥1 → crops + fills fit-rect; zoom<1 → shrinks fit-rect proportionally (centred) |
180180
| `draw2d(p)` | 540 | Main 2D render: decode bytes → LUT → ImageBitmap → `_blit2d`; then axes, scale bar, colorbar, overlay, markers |
181181
| `drawScaleBar2d(p)` | 587 | Physical scale bar using `fr.w` (fit-rect width) for pixel sizing |
182182
| `drawColorbar2d(p)` | 663 | Colorbar strip with gradient + tick labels |
@@ -251,8 +251,9 @@ Writes to `model.event_json` + `save_changes()`.
251251

252252
### Panel-level event handlers (lines 1618–1805)
253253
- **`_attachPanelEvents(p)`** (line 1619) — dispatches to kind-specific attach fn.
254-
- **`_canvasToImg2d(px,py,st,pw,ph)`** (line 1626) — inverts `_imgToCanvas2d`;
255-
derives fit-rect geometry from `_imgFitRect` so both directions are consistent.
254+
- **`_canvasToImg2d(px,py,st,pw,ph)`** (line 1626) — inverts `_imgToCanvas2d` exactly;
255+
uses the zoom≥1 pan/crop formula or the zoom<1 centred-shrink inverse so both
256+
directions are always consistent with `_blit2d`.
256257
- **`_attachEvents2d(p)`** (line 1636) — 2D mouse events:
257258
- **Wheel zoom** — calls `_canvasToImg2d` to find the image-space anchor
258259
before zoom; recomputes `center_x/y` via `_imgFitRect` so the same image

anyplotlib/figure_esm.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,13 @@ function render({ model, el }) {
506506
const { x, y, w, h } = _imgFitRect(st.image_width, st.image_height, pw, ph);
507507
const zoom = st.zoom, cx = st.center_x, cy = st.center_y;
508508
const iw = st.image_width, ih = st.image_height;
509+
if (zoom < 1.0) {
510+
// Zoom-out path: full image drawn centred inside a scaled-down fit-rect
511+
// (mirrors the zoom<1 branch in _blit2d exactly).
512+
const dstW = w * zoom, dstH = h * zoom;
513+
const dstX = x + (w - dstW) / 2, dstY = y + (h - dstH) / 2;
514+
return [dstX + (ix / iw) * dstW, dstY + (iy / ih) * dstH];
515+
}
509516
const visW = iw / zoom, visH = ih / zoom;
510517
const srcX = Math.max(0, Math.min(iw - visW, cx * iw - visW / 2));
511518
const srcY = Math.max(0, Math.min(ih - visH, cy * ih - visH / 2));
@@ -1647,6 +1654,12 @@ function render({ model, el }) {
16471654
const { x, y, w, h } = _imgFitRect(st.image_width, st.image_height, pw, ph);
16481655
const zoom = st.zoom, cx = st.center_x, cy = st.center_y;
16491656
const iw = st.image_width, ih = st.image_height;
1657+
if (zoom < 1.0) {
1658+
// Zoom-out path: inverse of the centred-shrink in _blit2d.
1659+
const dstW = w * zoom, dstH = h * zoom;
1660+
const dstX = x + (w - dstW) / 2, dstY = y + (h - dstH) / 2;
1661+
return [(px - dstX) / dstW * iw, (py - dstY) / dstH * ih];
1662+
}
16501663
const visW = iw / zoom, visH = ih / zoom;
16511664
const srcX = Math.max(0, Math.min(iw - visW, cx * iw - visW / 2));
16521665
const srcY = Math.max(0, Math.min(ih - visH, cy * ih - visH / 2));

0 commit comments

Comments
 (0)