Skip to content

Media Editor: auto zoom-out during freeform crop handle drag#77538

Closed
ramonjd wants to merge 8 commits intoWordPress:trunkfrom
ramonjd:update/image-cropper-freeform-zoom
Closed

Media Editor: auto zoom-out during freeform crop handle drag#77538
ramonjd wants to merge 8 commits intoWordPress:trunkfrom
ramonjd:update/image-cropper-freeform-zoom

Conversation

@ramonjd
Copy link
Copy Markdown
Member

@ramonjd ramonjd commented Apr 22, 2026

Summary

How it works

A transient isResizing flag gates a sub-unit-zoom regime in the cropper reducer:

  • BEGIN_RESIZE on handle pointerdown relaxes the zoom >= 1 floor and pins base* fields.
  • During drag, handleCropChange dispatches a combined SET_CROP_RECT + SET_ZOOM where zoom is computed so the growing crop fits the container with a small margin (RESIZE_FIT_MARGIN = 0.95).
  • restrictPanZoom in containment skips the cover-floor bump while the flag is set — the camera math is linear and handles zoom < 1 without modification (verified by test + JSDoc in createCamera).
  • END_RESIZE clears the flag; SETTLE_CROP then re-expands the crop, recenters, and enforceContainment restores the cover invariant. SETTLE_CROP also self-heals the flag so a caller that forgets END_RESIZE still lands in a coherent state.

Behavior is gated to freeform crops — fixed aspect-ratio presets are untouched.

Tests

  • New focused suite core/test/sub-unit-zoom.ts covers the sub-unit regime: flag transitions, sub-unit zoom through SET_ZOOM and enforceContainment, settle self-heal, zoom-back-to-≥1, and camera round-trip at zoom=0.5.
  • New integration test react/hooks/test/resize-zoom-out.ts exercises the full dispatch chain through the state hook.
  • The 12k-assertion preview-export-parity.ts suite is deliberately untouched and still green — the sub-unit regime is transient and never escapes into committed state.

Test plan

  • Drag the east/west/north/south handles outward on a 16:9 image — image scales down, handles keep tracking.
  • Drag the nw/ne/sw/se corners outward — same behavior.
  • Release — crop re-centers, zoom snaps to >= 1.
  • Drag a handle inward — image stays put until release.
  • With a fixed aspect ratio preset active — zoom-out does NOT engage; clamp behavior matches trunk.
  • Rotate (15 degrees) + drag — still works.
  • Flip + drag — still works.
  • Existing 12k preview-export parity suite still passes.

Follow-ups (not in this PR)

  • v4 smoother settle transition (width/height/left/top animation).
  • Approach-driven zoom-out (start shrinking before the handle reaches the edge).
  • createCamera -> getImageFit delegation refactor.

@github-actions
Copy link
Copy Markdown

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 props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@ramonjd ramonjd closed this Apr 22, 2026
@ramonjd ramonjd deleted the update/image-cropper-freeform-zoom branch April 22, 2026 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant