Image editor: hold Shift while resizing to lock current aspect ratio#77663
Image editor: hold Shift while resizing to lock current aspect ratio#77663andrewserong merged 2 commits intotrunkfrom
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
There was a problem hiding this comment.
Pull request overview
Adds “hold Shift to lock the current crop aspect ratio” behavior to the experimental media editor’s freeform rectangle crop stencil, keeping configured fixed aspectRatio behavior unchanged.
Changes:
- Capture
shiftKeystate during resize drags and route freeform resizing through a new “shift-locked” resize path. - Introduce
computeShiftLockedResizeRectto preserve the start-rect ratio during Shift+resize (including symmetric expansion for edge handles). - Add core unit tests covering representative corner/edge handles and bounds clamping.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| packages/media-editor/src/image-editor/react/components/stencils/rectangle-stencil.tsx | Tracks Shift during pointermove and selects locked/free/shift-locked resize math accordingly. |
| packages/media-editor/src/image-editor/core/stencil-math.ts | Adds computeShiftLockedResizeRect implementing “lock to start ratio while Shift held” logic. |
| packages/media-editor/src/image-editor/core/test/stencil-math.ts | Adds Jest tests for the new shift-locked resize math behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return computeLockedResizeRect( | ||
| drag, | ||
| clientX, | ||
| clientY, | ||
| imageSize, | ||
| bounds, | ||
| normalizedRatio | ||
| ); |
There was a problem hiding this comment.
Corner-handle behavior is delegated to computeLockedResizeRect(...) using normalizedRatio = s.width / s.height. Inside computeLockedResizeRect, the “driver axis” heuristic compares pixelDistW / pixelDistH (a pixel-space ratio) against normalizedRatio (normalized-space ratio), which can pick the wrong driving axis on non-square images and produce unintuitive resizing. Consider comparing like-for-like (either compare distW / distH to normalizedRatio, or compare pixelDistW / pixelDistH to the pixel-space ratio normalizedRatio * imageSize.width / imageSize.height).
There was a problem hiding this comment.
Good observation, but this is pre-existing logic in computeLockedResizeRect (introduced in #77479) that the regular fixed-aspect-ratio path also uses — not something this PR introduces or modifies. If the comparison is wrong, both the fixed-ratio and shift-ratio paths share the same heuristic. I'd rather address that as a separate fix so it can be reviewed against the existing tests for the locked-ratio path. Out of scope here.
There was a problem hiding this comment.
|
Size Change: +260 B (0%) Total Size: 7.78 MB 📦 View Changed
ℹ️ View Unchanged
|
|
Flaky tests detected in 78ee4da. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/24973189332
|
|
Now that #77664 has been merged, I'll give this one a rebase. |
Min-size clamping in computeShiftLockedResizeRect was applied to width and height independently, which could violate the locked ratio when one axis hit MIN_CROP_SIZE. Now the minimum is enforced on the driving axis (scaled by the ratio so the dependent axis also satisfies the minimum), and the dependent axis is recomputed from the ratio.
c2e529a to
78ee4da
Compare
andrewserong
left a comment
There was a problem hiding this comment.
Looking good! This feels like a nice quality of life improvement, and it feels pretty consistent to image editing apps, while also not interfering with the SHIFT behaviour when adjusting the crop handles via keyboard.
LGTM 🚀
|
The perf test is timing out (it's just taking too long so it gets cut off at 60min). That's unrelated to this PR, and the feature here is behind an experiment, so I'll merge this in now, anyway. |
Summary
Part of:
In the experimental media editor's image cropper, holding Shift while dragging a resize handle now locks the aspect ratio to the crop's current ratio. Only applies in freeform mode (when no fixed
aspectRatiois set); a configured aspect ratio still wins.2026-04-25.10.37.52.mp4
Test plan