photocn

Search

Search the docs

0

Crop & transform

How crop, straighten, perspective and rotate work together.

Crop works like the Photos app: every change can be undone or adjusted later. Edits never overwrite the original. The editor always starts from the original photo and applies the changes in the same order:

flip and rotate → perspective → straighten → crop → resize (only when exporting)
  • The crop is a window. Open the crop tool again and you can make it bigger.
  • The frame stays put. When you straighten or change perspective, the photo turns and zooms behind the frame so no empty corners show. Set straighten back to 0 and your original crop returns.
  • Rotating turns the whole picture, crop included. A 4:5 crop becomes 5:4.
  • There's no zoom slider. Make the crop smaller, or scroll or pinch inside the frame.
  • Resizing happens when you export, in the export panel.
"use client";

import { ImageEditorProvider } from "photocn/react";

import { ImageEditorCanvas } from "@/components/image-editor/canvas";
import { ImageEditorCrop } from "@/components/image-editor/crop-panel";

export default function CropDemo() {
  return (
    <ImageEditorProvider src="/samples/street.jpg" defaultTool="compose">
      <div className="grid h-[520px] grid-rows-[1fr_auto] overflow-hidden rounded-xl border bg-background sm:grid-cols-[1fr_300px] sm:grid-rows-1">
        <ImageEditorCanvas className="min-h-0 p-2" />
        <aside className="max-h-60 overflow-y-auto border-t sm:max-h-none sm:border-t-0 sm:border-l">
          <ImageEditorCrop />
        </aside>
      </div>
    </ImageEditorProvider>
  );
}

Keyboard shortcuts

KeysAction
R / ⇧RRotate right / left
H · VFlip horizontal · vertical
XSwitch portrait and landscape
[ · ]Straighten by 0.5° (⇧ for 5°)
ArrowsMove the photo under the frame
EscCancel the current drag
⌫Reset the crop
↵Done

From code

const { geometry } = useImageEditor();

geometry.rotate(1);                    // quarter turn clockwise
geometry.setAspectRatio("16:9");
geometry.toggleOrientation();          // 16:9 → 9:16
geometry.setStraighten(3.5);           // -45 to 45 degrees
geometry.setPerspective({ y: 0.25 });  // -1 to 1
geometry.setCrop({ x: 0.1, y: 0.1, width: 0.8, height: 0.8 });