# Image Cropper URL: https://ark-ui.com/docs/components/image-cropper Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/image-cropper.mdx Crop and transform images with zoom, rotation, and aspect ratio controls. --- ## Anatomy ```tsx ``` ## Examples ### Basic Set up a basic image cropper. Drag the handles to resize the selection, or drag inside to pan the image. **Example: basic** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import styles from 'styles/image-cropper.module.css' export const Basic = () => { return (
{ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import styles from 'styles/image-cropper.module.css' export const Basic = () => { return (
{(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{#each ImageCropper.handles as position}
{/each}
``` ### 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. **Example: aspect-ratio** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import { RectangleHorizontalIcon, SquareIcon, RectangleVerticalIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' const aspects = [ { label: '16:9', value: 16 / 9, icon: RectangleHorizontalIcon }, { label: '1:1', value: 1, icon: SquareIcon }, { label: '9:16', value: 9 / 16, icon: RectangleVerticalIcon }, ] export const AspectRatio = () => { const [aspectRatio, setAspectRatio] = useState(16 / 9) return (
{aspects.map((aspect) => ( ))}
{ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For, createSignal } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import { RectangleHorizontalIcon, SquareIcon, RectangleVerticalIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' const aspects = [ { label: '16:9', value: 16 / 9, icon: RectangleHorizontalIcon }, { label: '1:1', value: 1, icon: SquareIcon }, { label: '9:16', value: 9 / 16, icon: RectangleVerticalIcon }, ] export const AspectRatio = () => { const [aspectRatio, setAspectRatio] = createSignal(16 / 9) return (
{(aspect) => ( )}
{(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{#each aspects as aspect} {/each}
{#each ImageCropper.handles as position}
{/each}
``` ### Circle Crop Use `cropShape="circle"` for profile pictures or avatars. The selection becomes a circle instead of a rectangle. **Example: circle** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import styles from 'styles/image-cropper.module.css' export const Circle = () => { return (
{ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import styles from 'styles/image-cropper.module.css' export const Circle = () => { return (
{(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{#each ImageCropper.handles as position}
{/each}
``` ### Initial Crop Start with a pre-defined crop area using the `initialCrop` prop. Pass an object with `x`, `y`, `width`, and `height` in pixels. **Example: initial-crop** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import styles from 'styles/image-cropper.module.css' export const InitialCrop = () => { return (

Starts with a pre-defined crop area

{ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import styles from 'styles/image-cropper.module.css' export const InitialCrop = () => { return (

Starts with a pre-defined crop area

{(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte

Starts with a pre-defined crop area

{#each ImageCropper.handles as position}
{/each}
``` ### Controlled Zoom Control zoom programmatically with the `zoom` and `onZoomChange` props. Useful when you want external buttons to zoom in and out. **Example: controlled-zoom** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import { ZoomInIcon, ZoomOutIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const ControlledZoom = () => { const [zoom, setZoom] = useState(1) return (
{zoom.toFixed(1)}x
setZoom(e.zoom)}> {ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For, createSignal } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import { ZoomInIcon, ZoomOutIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const ControlledZoom = () => { const [zoom, setZoom] = createSignal(1) return (
{zoom().toFixed(1)}x
setZoom(e.zoom)}> {(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{zoom.toFixed(1)}x
{#each ImageCropper.handles as position}
{/each}
``` ### Zoom Limits Set `minZoom` and `maxZoom` to constrain how far users can zoom. Prevents over-zooming or zooming out past the image bounds. **Example: zoom-limits** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import { ZoomInIcon, ZoomOutIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const ZoomLimits = () => { const [zoom, setZoom] = useState(1) const minZoom = 0.5 const maxZoom = 2 return (
{zoom.toFixed(1)}x

Zoom constrained between {minZoom}x and {maxZoom}x

setZoom(e.zoom)} minZoom={minZoom} maxZoom={maxZoom} > {ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For, createSignal } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import { ZoomInIcon, ZoomOutIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const ZoomLimits = () => { const [zoom, setZoom] = createSignal(1) const minZoom = 0.5 const maxZoom = 2 return (
{zoom().toFixed(1)}x

Zoom constrained between {minZoom}x and {maxZoom}x

setZoom(e.zoom)} minZoom={minZoom} maxZoom={maxZoom} > {(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{zoom.toFixed(1)}x

Zoom constrained between {minZoom}x and {maxZoom}x

{#each ImageCropper.handles as position}
{/each}
``` ### Rotation Rotate the image with the `rotation` and `onRotationChange` props. Values are in degrees—common increments are 90 or 180. **Example: rotation** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import { RotateCcwIcon, RotateCwIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const Rotation = () => { const [rotation, setRotation] = useState(0) return (
{rotation}°
setRotation(e.rotation)}> {ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For, createSignal } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import { RotateCcwIcon, RotateCwIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const Rotation = () => { const [rotation, setRotation] = createSignal(0) return (
{rotation()}deg
setRotation(e.rotation)}> {(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{rotation}deg
(rotation = e.rotation)}> {#each ImageCropper.handles as position}
{/each}
``` ### Flip Flip the image horizontally or vertically using the `flip` prop. Pass an object with `horizontal` and `vertical` booleans. **Example: flip** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import { FlipHorizontalIcon, FlipVerticalIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const Flip = () => { const [flip, setFlip] = useState({ horizontal: false, vertical: false }) return (
setFlip(e.flip)}> {ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For, createSignal } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import { FlipHorizontalIcon, FlipVerticalIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const Flip = () => { const [flip, setFlip] = createSignal({ horizontal: false, vertical: false }) return (
setFlip(e.flip)}> {(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
(flip = e.flip)}> {#each ImageCropper.handles as position}
{/each}
``` ### Min and Max Size Constrain the crop area size with `minWidth`, `minHeight`, `maxWidth`, and `maxHeight`. Keeps the selection within sensible bounds. **Example: min-max-size** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import styles from 'styles/image-cropper.module.css' export const MinMaxSize = () => { return (

Crop area constrained to min 80px and max 200px

{ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import styles from 'styles/image-cropper.module.css' export const MinMaxSize = () => { return (

Crop area constrained to min 80px and max 200px

{(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte

Crop area constrained to min 80px and max 200px

{#each ImageCropper.handles as position}
{/each}
``` ### Fixed Crop Area Set `fixedCropArea` to `true` when the crop area should stay fixed while the image moves underneath. Useful for overlay-style cropping. **Example: fixed** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import styles from 'styles/image-cropper.module.css' export const Fixed = () => { return (
) } ``` #### Solid ```tsx import { ImageCropper } from '@ark-ui/solid/image-cropper' import styles from 'styles/image-cropper.module.css' export const Fixed = () => { return (
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
``` ### 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. **Example: crop-preview** #### React ```tsx import { ImageCropper, useImageCropper } from '@ark-ui/react/image-cropper' import { CropIcon } from 'lucide-react' import { useState } from 'react' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const CropPreview = () => { const imageCropper = useImageCropper() const [preview, setPreview] = useState(null) const handleCrop = async () => { const result = await imageCropper.getCroppedImage({ output: 'dataUrl' }) if (typeof result === 'string') { setPreview(result) } } return (
{ImageCropper.handles.map((position) => (
))}
Preview {preview && Cropped preview}
) } ``` #### Solid ```tsx import { For, createSignal, Show } from 'solid-js' import { ImageCropper, useImageCropper } from '@ark-ui/solid/image-cropper' import { CropIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const CropPreview = () => { const imageCropper = useImageCropper() const [preview, setPreview] = createSignal(null) const handleCrop = async () => { const result = await imageCropper().getCroppedImage({ output: 'dataUrl' }) if (typeof result === 'string') { setPreview(result) } } return (
{(position) => (
)}
Preview Cropped preview
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{#each ImageCropper.handles as position}
{/each}
Preview {#if preview} Cropped preview {/if}
``` ### Reset The context exposes a `reset()` method that restores the image to its initial state. Handy for an "undo" or "start over" button. **Example: reset** #### React ```tsx import { ImageCropper, useImageCropper } from '@ark-ui/react/image-cropper' import { FlipHorizontalIcon, RotateCwIcon, RotateCcwIcon, RefreshCwIcon, ZoomInIcon, ZoomOutIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const Reset = () => { const imageCropper = useImageCropper() return (
{ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For } from 'solid-js' import { ImageCropper, useImageCropper } from '@ark-ui/solid/image-cropper' import { FlipHorizontalIcon, RotateCwIcon, RotateCcwIcon, RefreshCwIcon, ZoomInIcon, ZoomOutIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const Reset = () => { const imageCropper = useImageCropper() return (
{(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{#each ImageCropper.handles as position}
{/each}
``` ### Events Listen to `onCropChange` and `onZoomChange` to track crop position and zoom level. Use these to sync with external state or show live previews. **Example: events** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import { useState } from 'react' import styles from 'styles/image-cropper.module.css' export const Events = () => { const [cropData, setCropData] = useState({ x: 0, y: 0, width: 0, height: 0 }) const [zoom, setZoom] = useState(1) return (
setCropData(e.crop)} onZoomChange={(e) => setZoom(e.zoom)} > {ImageCropper.handles.map((position) => (
))}
Zoom {zoom.toFixed(2)}x
Position {Math.round(cropData.x)}, {Math.round(cropData.y)}
Size {Math.round(cropData.width)} × {Math.round(cropData.height)}
) } ``` #### Solid ```tsx import { For, createSignal } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import styles from 'styles/image-cropper.module.css' export const Events = () => { const [cropData, setCropData] = createSignal({ x: 0, y: 0, width: 0, height: 0 }) const [zoom, setZoom] = createSignal(1) return (
setCropData(e.crop)} onZoomChange={(e) => setZoom(e.zoom)} > {(position) => (
)}
Zoom {zoom().toFixed(2)}x
Position {Math.round(cropData().x)}, {Math.round(cropData().y)}
Size {Math.round(cropData().width)} x {Math.round(cropData().height)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
(cropData = e.crop)} onZoomChange={(e) => (zoom = e.zoom)} > {#each ImageCropper.handles as position}
{/each}
Zoom {zoom.toFixed(2)}x
Position {Math.round(cropData.x)}, {Math.round(cropData.y)}
Size {Math.round(cropData.width)} x {Math.round(cropData.height)}
``` ### Context Use `ImageCropper.Context` to access the cropper API from anywhere inside the root. You get methods like `zoomBy`, `rotateBy`, and `setZoom`. **Example: context** #### React ```tsx import { ImageCropper } from '@ark-ui/react/image-cropper' import { ZoomInIcon, ZoomOutIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const Context = () => { return (
{(context) => (
{context.zoom.toFixed(1)}x
)}
{ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For } from 'solid-js' import { ImageCropper } from '@ark-ui/solid/image-cropper' import { ZoomInIcon, ZoomOutIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const Context = () => { return (
{(context) => (
{context().zoom.toFixed(1)}x
)}
{(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{#snippet render(context: UseImageCropperContext)}
{context().zoom.toFixed(1)}x
{/snippet}
{#each ImageCropper.handles as position}
{/each}
``` ### 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. **Example: root-provider** #### React ```tsx import { ImageCropper, useImageCropper } from '@ark-ui/react/image-cropper' import { ZoomInIcon, ZoomOutIcon } from 'lucide-react' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const RootProvider = () => { const imageCropper = useImageCropper() return (
{imageCropper.zoom.toFixed(1)}x
{ImageCropper.handles.map((position) => (
))}
) } ``` #### Solid ```tsx import { For } from 'solid-js' import { ImageCropper, useImageCropper } from '@ark-ui/solid/image-cropper' import { ZoomInIcon, ZoomOutIcon } from 'lucide-solid' import button from 'styles/button.module.css' import styles from 'styles/image-cropper.module.css' export const RootProvider = () => { const imageCropper = useImageCropper() return (
{imageCropper().zoom.toFixed(1)}x
{(position) => (
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
{imageCropper().zoom.toFixed(1)}x
{#each ImageCropper.handles as position}
{/each}
``` ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `aspectRatio` | `number` | No | 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` | `'circle' | 'rectangle'` | No | The shape of the crop area. | | `defaultFlip` | `FlipState` | No | The initial flip state to apply to the image. | | `defaultRotation` | `number` | No | The initial rotation to apply to the image in degrees. | | `defaultZoom` | `number` | No | The initial zoom factor to apply to the image. | | `fixedCropArea` | `boolean` | No | Whether the crop area is fixed in size and position. | | `flip` | `FlipState` | No | The controlled flip state of the image. | | `ids` | `Partial<{ root: string viewport: string image: string selection: string handle: (position: string) => string }>` | No | The ids of the image cropper elements | | `initialCrop` | `Rect` | No | The initial rectangle of the crop area. If not provided, a smart default will be computed based on viewport size and aspect ratio. | | `maxHeight` | `number` | No | The maximum height of the crop area | | `maxWidth` | `number` | No | The maximum width of the crop area | | `maxZoom` | `number` | No | The maximum zoom factor allowed. | | `minHeight` | `number` | No | The minimum height of the crop area | | `minWidth` | `number` | No | The minimum width of the crop area | | `minZoom` | `number` | No | The minimum zoom factor allowed. | | `nudgeStep` | `number` | No | The base nudge step for keyboard arrow keys (in pixels). | | `nudgeStepCtrl` | `number` | No | The nudge step when Ctrl/Cmd key is held (in pixels). | | `nudgeStepShift` | `number` | No | The nudge step when Shift key is held (in pixels). | | `onCropChange` | `(details: CropChangeDetails) => void` | No | Callback fired when the crop area changes. | | `onFlipChange` | `(details: FlipChangeDetails) => void` | No | Callback fired when the flip state changes. | | `onRotationChange` | `(details: RotationChangeDetails) => void` | No | Callback fired when the rotation changes. | | `onZoomChange` | `(details: ZoomChangeDetails) => void` | No | Callback fired when the zoom level changes. | | `rotation` | `number` | No | The controlled rotation of the image in degrees (0 - 360). | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identify accessibility elements and their states. | | `zoom` | `number` | No | The controlled zoom level of the image. | | `zoomSensitivity` | `number` | No | Controls how responsive pinch-to-zoom is. | | `zoomStep` | `number` | No | The amount of zoom applied per wheel step. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | root | | `[data-fixed]` | | | `[data-shape]` | | | `[data-pinch]` | | | `[data-dragging]` | Present when in the dragging state | | `[data-panning]` | | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--crop-width` | The width of the Root | | `--crop-height` | The height of the Root | | `--crop-x` | The crop x value for the Root | | `--crop-y` | The crop y value for the Root | | `--image-zoom` | The image zoom value for the Root | | `--image-rotation` | The image rotation value for the Root | | `--image-offset-x` | The offset position for image | | `--image-offset-y` | The offset position for image | **Grid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `'horizontal' | 'vertical'` | Yes | The axis of the grid lines to display | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Grid Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | grid | | `[data-axis]` | The axis to resize | | `[data-dragging]` | Present when in the dragging state | | `[data-panning]` | | **Handle Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `position` | `HandlePosition` | Yes | The position of the handle | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Handle Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | handle | | `[data-position]` | | | `[data-disabled]` | Present when disabled | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | image | | `[data-ready]` | | | `[data-flip-horizontal]` | | | `[data-flip-vertical]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseImageCropperReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Selection Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Selection Data Attributes:** | Attribute | Value | |-----------|-------| | `[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 Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | viewport | | `[data-disabled]` | Present when disabled | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `aspectRatio` | `number` | No | 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'` | No | The shape of the crop area. | | `defaultFlip` | `FlipState` | No | The initial flip state to apply to the image. | | `defaultRotation` | `number` | No | The initial rotation to apply to the image in degrees. | | `defaultZoom` | `number` | No | The initial zoom factor to apply to the image. | | `fixedCropArea` | `boolean` | No | Whether the crop area is fixed in size and position. | | `flip` | `FlipState` | No | The controlled flip state of the image. | | `ids` | `Partial<{ root: string viewport: string image: string selection: string handle: (position: string) => string }>` | No | The ids of the image cropper elements | | `initialCrop` | `Rect` | No | The initial rectangle of the crop area. If not provided, a smart default will be computed based on viewport size and aspect ratio. | | `maxHeight` | `number` | No | The maximum height of the crop area | | `maxWidth` | `number` | No | The maximum width of the crop area | | `maxZoom` | `number` | No | The maximum zoom factor allowed. | | `minHeight` | `number` | No | The minimum height of the crop area | | `minWidth` | `number` | No | The minimum width of the crop area | | `minZoom` | `number` | No | The minimum zoom factor allowed. | | `nudgeStep` | `number` | No | The base nudge step for keyboard arrow keys (in pixels). | | `nudgeStepCtrl` | `number` | No | The nudge step when Ctrl/Cmd key is held (in pixels). | | `nudgeStepShift` | `number` | No | The nudge step when Shift key is held (in pixels). | | `onCropChange` | `(details: CropChangeDetails) => void` | No | Callback fired when the crop area changes. | | `onFlipChange` | `(details: FlipChangeDetails) => void` | No | Callback fired when the flip state changes. | | `onRotationChange` | `(details: RotationChangeDetails) => void` | No | Callback fired when the rotation changes. | | `onZoomChange` | `(details: ZoomChangeDetails) => void` | No | Callback fired when the zoom level changes. | | `rotation` | `number` | No | The controlled rotation of the image in degrees (0 - 360). | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identify accessibility elements and their states. | | `zoom` | `number` | No | The controlled zoom level of the image. | | `zoomSensitivity` | `number` | No | Controls how responsive pinch-to-zoom is. | | `zoomStep` | `number` | No | The amount of zoom applied per wheel step. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | root | | `[data-fixed]` | | | `[data-shape]` | | | `[data-pinch]` | | | `[data-dragging]` | Present when in the dragging state | | `[data-panning]` | | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--crop-width` | The width of the Root | | `--crop-height` | The height of the Root | | `--crop-x` | The crop x value for the Root | | `--crop-y` | The crop y value for the Root | | `--image-zoom` | The image zoom value for the Root | | `--image-rotation` | The image rotation value for the Root | | `--image-offset-x` | The offset position for image | | `--image-offset-y` | The offset position for image | **Grid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `'horizontal' | 'vertical'` | Yes | The axis of the grid lines to display | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Grid Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | grid | | `[data-axis]` | The axis to resize | | `[data-dragging]` | Present when in the dragging state | | `[data-panning]` | | **Handle Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `position` | `HandlePosition` | Yes | The position of the handle | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Handle Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | handle | | `[data-position]` | | | `[data-disabled]` | Present when disabled | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'img'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | image | | `[data-ready]` | | | `[data-flip-horizontal]` | | | `[data-flip-vertical]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseImageCropperReturn` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Selection Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Selection Data Attributes:** | Attribute | Value | |-----------|-------| | `[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 Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | viewport | | `[data-disabled]` | Present when disabled | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `aspectRatio` | `number` | No | 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` | `'circle' | 'rectangle'` | No | The shape of the crop area. | | `defaultFlip` | `FlipState` | No | The initial flip state to apply to the image. | | `defaultRotation` | `number` | No | The initial rotation to apply to the image in degrees. | | `defaultZoom` | `number` | No | The initial zoom factor to apply to the image. | | `fixedCropArea` | `boolean` | No | Whether the crop area is fixed in size and position. | | `flip` | `FlipState` | No | The controlled flip state of the image. | | `ids` | `Partial<{ root: string viewport: string image: string selection: string handle: (position: string) => string }>` | No | The ids of the image cropper elements | | `initialCrop` | `Rect` | No | The initial rectangle of the crop area. If not provided, a smart default will be computed based on viewport size and aspect ratio. | | `maxHeight` | `number` | No | The maximum height of the crop area | | `maxWidth` | `number` | No | The maximum width of the crop area | | `maxZoom` | `number` | No | The maximum zoom factor allowed. | | `minHeight` | `number` | No | The minimum height of the crop area | | `minWidth` | `number` | No | The minimum width of the crop area | | `minZoom` | `number` | No | The minimum zoom factor allowed. | | `nudgeStep` | `number` | No | The base nudge step for keyboard arrow keys (in pixels). | | `nudgeStepCtrl` | `number` | No | The nudge step when Ctrl/Cmd key is held (in pixels). | | `nudgeStepShift` | `number` | No | The nudge step when Shift key is held (in pixels). | | `rotation` | `number` | No | The controlled rotation of the image in degrees (0 - 360). | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identify accessibility elements and their states. | | `zoom` | `number` | No | The controlled zoom level of the image. | | `zoomSensitivity` | `number` | No | Controls how responsive pinch-to-zoom is. | | `zoomStep` | `number` | No | The amount of zoom applied per wheel step. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | root | | `[data-fixed]` | | | `[data-shape]` | | | `[data-pinch]` | | | `[data-dragging]` | Present when in the dragging state | | `[data-panning]` | | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--crop-width` | The width of the Root | | `--crop-height` | The height of the Root | | `--crop-x` | The crop x value for the Root | | `--crop-y` | The crop y value for the Root | | `--image-zoom` | The image zoom value for the Root | | `--image-rotation` | The image rotation value for the Root | | `--image-offset-x` | The offset position for image | | `--image-offset-y` | The offset position for image | **Grid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `'horizontal' | 'vertical'` | Yes | The axis of the grid lines to display | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Grid Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | grid | | `[data-axis]` | The axis to resize | | `[data-dragging]` | Present when in the dragging state | | `[data-panning]` | | **Handle Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `position` | `HandlePosition` | Yes | The position of the handle | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Handle Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | handle | | `[data-position]` | | | `[data-disabled]` | Present when disabled | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | image | | `[data-ready]` | | | `[data-flip-horizontal]` | | | `[data-flip-vertical]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `ImageCropperApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Selection Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Selection Data Attributes:** | Attribute | Value | |-----------|-------| | `[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 Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | viewport | | `[data-disabled]` | Present when disabled | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `aspectRatio` | `number` | No | 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'` | No | The shape of the crop area. | | `defaultFlip` | `FlipState` | No | The initial flip state to apply to the image. | | `defaultRotation` | `number` | No | The initial rotation to apply to the image in degrees. | | `defaultZoom` | `number` | No | The initial zoom factor to apply to the image. | | `fixedCropArea` | `boolean` | No | Whether the crop area is fixed in size and position. | | `flip` | `FlipState` | No | The controlled flip state of the image. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string viewport: string image: string selection: string handle: (position: string) => string }>` | No | The ids of the image cropper elements | | `initialCrop` | `Rect` | No | The initial rectangle of the crop area. If not provided, a smart default will be computed based on viewport size and aspect ratio. | | `maxHeight` | `number` | No | The maximum height of the crop area | | `maxWidth` | `number` | No | The maximum width of the crop area | | `maxZoom` | `number` | No | The maximum zoom factor allowed. | | `minHeight` | `number` | No | The minimum height of the crop area | | `minWidth` | `number` | No | The minimum width of the crop area | | `minZoom` | `number` | No | The minimum zoom factor allowed. | | `nudgeStep` | `number` | No | The base nudge step for keyboard arrow keys (in pixels). | | `nudgeStepCtrl` | `number` | No | The nudge step when Ctrl/Cmd key is held (in pixels). | | `nudgeStepShift` | `number` | No | The nudge step when Shift key is held (in pixels). | | `onCropChange` | `(details: CropChangeDetails) => void` | No | Callback fired when the crop area changes. | | `onFlipChange` | `(details: FlipChangeDetails) => void` | No | Callback fired when the flip state changes. | | `onRotationChange` | `(details: RotationChangeDetails) => void` | No | Callback fired when the rotation changes. | | `onZoomChange` | `(details: ZoomChangeDetails) => void` | No | Callback fired when the zoom level changes. | | `ref` | `Element` | No | | | `rotation` | `number` | No | The controlled rotation of the image in degrees (0 - 360). | | `translations` | `IntlTranslations` | No | Specifies the localized strings that identify accessibility elements and their states. | | `zoom` | `number` | No | The controlled zoom level of the image. | | `zoomSensitivity` | `number` | No | Controls how responsive pinch-to-zoom is. | | `zoomStep` | `number` | No | The amount of zoom applied per wheel step. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | root | | `[data-fixed]` | | | `[data-shape]` | | | `[data-pinch]` | | | `[data-dragging]` | Present when in the dragging state | | `[data-panning]` | | **Root CSS Variables:** | Variable | Description | |----------|-------------| | `--crop-width` | The width of the Root | | `--crop-height` | The height of the Root | | `--crop-x` | The crop x value for the Root | | `--crop-y` | The crop y value for the Root | | `--image-zoom` | The image zoom value for the Root | | `--image-rotation` | The image rotation value for the Root | | `--image-offset-x` | The offset position for image | | `--image-offset-y` | The offset position for image | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UseImageCropperContext]>` | No | | **Grid Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `axis` | `'horizontal' | 'vertical'` | Yes | The axis of the grid lines to display | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Grid Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | grid | | `[data-axis]` | The axis to resize | | `[data-dragging]` | Present when in the dragging state | | `[data-panning]` | | **Handle Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `position` | `HandlePosition` | Yes | The position of the handle | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Handle Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | handle | | `[data-position]` | | | `[data-disabled]` | Present when disabled | **Image Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'img'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Image Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | image | | `[data-ready]` | | | `[data-flip-horizontal]` | | | `[data-flip-vertical]` | | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseImageCropperReturn` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Selection Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Selection Data Attributes:** | Attribute | Value | |-----------|-------| | `[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 Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Viewport Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | image-cropper | | `[data-part]` | viewport | | `[data-disabled]` | Present when disabled | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `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) => 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` | 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. |