Components
Image cropper

Image Cropper

Crop and transform images with zoom, rotation, and aspect ratio controls.

Loading...

Anatomy

<ImageCropper.Root>
  <ImageCropper.Viewport>
    <ImageCropper.Image />
    <ImageCropper.Selection>
      <ImageCropper.Handle />
      <ImageCropper.Grid />
    </ImageCropper.Selection>
  </ImageCropper.Viewport>
</ImageCropper.Root>

Examples

Basic

Set up a basic image cropper. Drag the handles to resize the selection, or drag inside to pan the image.

Aspect Ratio

Lock the crop area to a specific aspect ratio. Use the aspectRatio prop—pass a number like 16/9 for widescreen or 1 for square.

Circle Crop

Use cropShape="circle" for profile pictures or avatars. The selection becomes a circle instead of a rectangle.

Initial Crop

Start with a pre-defined crop area using the initialCrop prop. Pass an object with x, y, width, and height in pixels.

Controlled Zoom

Control zoom programmatically with the zoom and onZoomChange props. Useful when you want external buttons to zoom in and out.

Zoom Limits

Set minZoom and maxZoom to constrain how far users can zoom. Prevents over-zooming or zooming out past the image bounds.

Rotation

Rotate the image with the rotation and onRotationChange props. Values are in degrees—common increments are 90 or 180.

Flip

Flip the image horizontally or vertically using the flip prop. Pass an object with horizontal and vertical booleans.

Min and Max Size

Constrain the crop area size with minWidth, minHeight, maxWidth, and maxHeight. Keeps the selection within sensible bounds.

Fixed Crop Area

Set fixedCropArea to true when the crop area should stay fixed while the image moves underneath. Useful for overlay-style cropping.

Crop Preview

Use getCroppedImage() from the context to get the cropped result. Call it with { output: 'dataUrl' } for a base64 string you can use in an img src.

Reset

The context exposes a reset() method that restores the image to its initial state. Handy for an "undo" or "start over" button.

Events

Listen to onCropChange and onZoomChange to track crop position and zoom level. Use these to sync with external state or show live previews.

Context

Use ImageCropper.Context to access the cropper API from anywhere inside the root. You get methods like zoomBy, rotateBy, and setZoom.

Root Provider

Use RootProvider with useImageCropper when you need to control the cropper from outside the component tree. Build custom toolbars or integrate with form state.

API Reference

Props

Root

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
aspectRatio
number

The aspect ratio to maintain for the crop area (width / height). For example, an aspect ratio of 16 / 9 will maintain a width to height ratio of 16:9. If not provided, the crop area can be freely resized.

cropShape'rectangle'
'circle' | 'rectangle'

The shape of the crop area.

defaultFlip{ horizontal: false, vertical: false }
FlipState

The initial flip state to apply to the image.

defaultRotation0
number

The initial rotation to apply to the image in degrees.

defaultZoom1
number

The initial zoom factor to apply to the image.

fixedCropAreafalse
boolean

Whether the crop area is fixed in size and position.

flip
FlipState

The controlled flip state of the image.

ids
Partial<{ root: string viewport: string image: string selection: string handle: (position: string) => string }>

The ids of the image cropper elements

initialCrop
Rect

The initial rectangle of the crop area. If not provided, a smart default will be computed based on viewport size and aspect ratio.

maxHeightInfinity
number

The maximum height of the crop area

maxWidthInfinity
number

The maximum width of the crop area

maxZoom5
number

The maximum zoom factor allowed.

minHeight40
number

The minimum height of the crop area

minWidth40
number

The minimum width of the crop area

minZoom1
number

The minimum zoom factor allowed.

nudgeStep1
number

The base nudge step for keyboard arrow keys (in pixels).

nudgeStepCtrl50
number

The nudge step when Ctrl/Cmd key is held (in pixels).

nudgeStepShift10
number

The nudge step when Shift key is held (in pixels).

onCropChange
(details: CropChangeDetails) => void

Callback fired when the crop area changes.

onFlipChange
(details: FlipChangeDetails) => void

Callback fired when the flip state changes.

onRotationChange
(details: RotationChangeDetails) => void

Callback fired when the rotation changes.

onZoomChange
(details: ZoomChangeDetails) => void

Callback fired when the zoom level changes.

rotation
number

The controlled rotation of the image in degrees (0 - 360).

translations
IntlTranslations

Specifies the localized strings that identify accessibility elements and their states.

zoom
number

The controlled zoom level of the image.

zoomSensitivity2
number

Controls how responsive pinch-to-zoom is.

zoomStep0.1
number

The amount of zoom applied per wheel step.

AttributeDescription
[data-scope]image-cropper
[data-part]root
[data-fixed]
[data-shape]
[data-pinch]
[data-dragging]Present when in the dragging state
[data-panning]
CSS VariableDescription
--crop-widthThe width of the Root
--crop-heightThe height of the Root
--crop-xThe crop x value for the Root
--crop-yThe crop y value for the Root
--image-zoomThe image zoom value for the Root
--image-rotationThe image rotation value for the Root
--image-offset-xThe offset position for image
--image-offset-yThe offset position for image

Grid

Renders a <div> element.

PropDefaultType
axis
'horizontal' | 'vertical'

The axis of the grid lines to display

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]image-cropper
[data-part]grid
[data-axis]The axis to resize
[data-dragging]Present when in the dragging state
[data-panning]

Handle

Renders a <div> element.

PropDefaultType
position
HandlePosition

The position of the handle

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]image-cropper
[data-part]handle
[data-position]
[data-disabled]Present when disabled

Image

Renders a <img> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]image-cropper
[data-part]image
[data-ready]
[data-flip-horizontal]
[data-flip-vertical]

RootProvider

Renders a <div> element.

PropDefaultType
value
UseImageCropperReturn

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Selection

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]image-cropper
[data-part]selection
[data-disabled]Present when disabled
[data-shape]
[data-measured]
[data-dragging]Present when in the dragging state
[data-panning]

Viewport

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]image-cropper
[data-part]viewport
[data-disabled]Present when disabled

Context

API

PropertyType
zoom
number

The current zoom level of the image.

rotation
number

The current rotation of the image in degrees.

flip
FlipState

The current flip state of the image.

crop
Rect

The current crop area rectangle in viewport coordinates.

offset
Point

The current offset (pan position) of the image.

naturalSize
Size

The natural (original) size of the image.

viewportRect
BoundingRect

The viewport rectangle dimensions and position.

dragging
boolean

Whether the crop area is currently being dragged.

panning
boolean

Whether the image is currently being panned.

setZoom
(zoom: number) => void

Function to set the zoom level of the image.

zoomBy
(delta: number) => void

Function to zoom the image by a relative amount.

setRotation
(rotation: number) => void

Function to set the rotation of the image.

rotateBy
(degrees: number) => void

Function to rotate the image by a relative amount in degrees.

setFlip
(flip: Partial<FlipState>) => void

Function to set the flip state of the image.

flipHorizontally
(value?: boolean) => void

Function to flip the image horizontally. Pass a boolean to set explicitly or omit to toggle.

flipVertically
(value?: boolean) => void

Function to flip the image vertically. Pass a boolean to set explicitly or omit to toggle.

resize
(handlePosition: HandlePosition, delta: number) => void

Function to resize the crop area from a handle programmatically.

reset
() => void

Function to reset the cropper to its initial state.

getCroppedImage
(options?: GetCroppedImageOptions) => Promise<string | Blob>

Function to get the cropped image with all transformations applied. Returns a Promise that resolves to either a Blob or data URL.

getCropData
() => CropData

Function to get the crop data in natural image pixel coordinates. These coordinates are relative to the original image dimensions, accounting for zoom, rotation, and flip transformations. Use this for server-side cropping or state persistence.