`onCropAreaChange` runs whenever a valid crop changes. `onCropComplete` runs after drag or wheel interaction and after discrete keyboard operations, making it a better persistence boundary.
## Geometry functions {#geometry}
`getCoverScale`, `getCropperBounds`, `constrainCropperValue`, `getCropArea`, and `zoomCropperValueAtPoint` are DOM-independent pure functions that can be reused in custom interfaces and tests.
const result = await cropperRef.current?.getCropImage({
outputType: "base64",
type: "image/jpeg",
quality: 0.9,
width: 1200,
})
<Cropper ref={cropperRef} src={src} />
```
`getCropImage()` returns `undefined` until the image is ready. `outputType` defaults to `"blob"`; `"base64"` returns a data URL suitable for previews or form values. Quality must be between `0` and `1`.
Use the pure function when no component instance is available:
Supplying only `width` or `height` preserves the crop aspect ratio. `shape: "circle"` clips through an ellipse; provide `background` when an opaque JPEG background is required. `getCropImage(source, area, options)` is the corresponding pure function for Blob/base64 output.
`CropperHandle` exposes `element`, `getCropArea()`, `getCropImage(options)`, and `reset()`. Use `rootRef` when a raw DOM ref is needed; the component `ref` is reserved for the imperative handle.
A remote image server must return CORS headers that permit Canvas use. Pass `crossOrigin="anonymous"` to `Cropper` and the matching `crossOrigin` option to `cropImage`; otherwise the browser may taint the Canvas and prevent Blob encoding.