[MAIC Editor] Image crop as a proper editor-surface operation
- Dominant language
- TypeScript
- Stars
- 37.7k
- Forks
- 5.9k
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 193
Description
Parent: #646 (Phase 2, Track 1) · Relates: #647 · Crop was removed from #648 (PR3b).
PR3b exposed a Crop button that reused the renderer's existing clip path (`ImageElement.handleClip` via `clipingImageElementId`). That path isn't integrated with the editor surface, so it was removed from PR3b (which is surface-only / playback-byte-unchanged). This issue tracks doing crop properly.
## Requirements
1. **Canonical, undoable op** — route the crop commit through `useSlideEditSession.applyOp` (an `element.update {clip, …}`) so it pushes an undo step on every confirm path. Today `handleClip` commits via the renderer's `updateElement()`; an Enter-confirmed crop has no pointer gesture, so the edit-session treats it as a non-user normalization commit and skips the undo stack.
2. **Defined geometry invariant** — `handleClip` currently writes `clip` *and* element geometry (`left/top/width/height`), which behaves like resize rather than crop. Decide and enforce the invariant (e.g. crop preserves the outer frame), document it, and test it.
3. **Exit / cancel** — clicking blank canvas (which clears selection and hides the anchored bar) must also confirm-or-cancel crop and clear `clipingImageElementId`; add an explicit cancel (Esc). No stuck controls-less crop state.
4. **Flip-aware** — the crop-mode branch renders `ImageClipHandler` without `flipStyle`, so a flipped image is cropped against its unflipped pixels. The clip UI + range calc must operate on the flipped image so the result matches what the user saw.
5. **Tests** — per-op PPTX round-trip for `clip` → ``, plus e2e covering enter-crop → adjust → confirm → undo, and flip+crop.
## Scope
Requires renderer changes (`ImageElement`, `ImageClipHandler`) — distinct from PR3b's surface-only scope. Likely its own Track-1 sub-PR targeting `feat/maic-editor-v1`.
Contributor guide
Research direction
Trace useSlideEditSession.applyOp and the renderer's ImageElement.handleClip, then inspect ImageClipHandler and the crop-mode branch. Define and document the crop geometry invariant, ensure confirm/cancel, undo, and flip-aware behavior work, and add the mentioned per-op PPTX round-trip and e2e coverage for confirm, undo, and flip+crop.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100