Reference
Options, methods and events
Options
The crop
| Option | Type | Default | What it does |
|---|---|---|---|
value |
Blob | string |
— | A file or a URL to open straight away. |
aspect |
number | [number, number] | null |
null |
A shape, a range, or free. |
aspects |
{ label, value }[] |
— | Shapes offered as buttons. |
mode |
'free' | 'fixed' |
'free' |
Crop over a still picture, or a fixed hole with the picture moving under it. |
minWidth / minHeight |
number |
16 |
The smallest the crop may be, in source pixels. |
minSourceWidth / minSourceHeight |
number |
— | Turn away a picture smaller than this. |
maxZoom |
number |
8 |
|
zoomStep |
number |
0.1 |
How much a wheel notch moves. |
grid |
boolean |
true |
The rule-of-thirds grid while dragging. |
rotatable |
boolean |
true |
Show the turn and flip buttons. |
preview |
boolean |
false |
A live thumbnail of the output beside the tools. |
live |
boolean |
false |
Call onCrop with a fresh picture on every change. |
The output
These are the defaults for toBlob, toFile and toDataURL, and every one can be overridden per
call.
| Option | Type | Default | What it does |
|---|---|---|---|
maxWidth / maxHeight |
number |
— | Cap the output. Never enlarges. |
width / height |
number |
— | Force an exact size. |
type |
'image/png' | 'image/jpeg' | 'image/webp' |
see below | |
quality |
number |
0.9 |
0–1, for JPEG and WebP. |
round |
boolean |
false |
Cut the output to an ellipse, transparently. |
background |
string |
transparent | What shows where the picture does not reach. |
With no type: a PNG or GIF source stays a PNG, so transparency survives; anything else becomes WebP
where the browser can write it, and JPEG where it cannot.
The rest
locale, theme, classNames, strings — as in every Devix widget.
Callbacks
createImageCropper(input, {
onPick: (file, picker) => {}, // a picture was opened
onChange: (crop, picker) => {}, // the crop moved; `crop` is in source pixels
onCrop: (blob, picker) => {}, // a fresh picture, when `live` is on
onRemove: (picker) => {},
onError: (message, picker) => {}, // not a picture, or too small
});
Methods
await picker.open(fileOrUrl);
await picker.toBlob(options);
await picker.toFile(name, options);
await picker.toDataURL(options);
picker.getCrop(); // { x, y, width, height } in pixels of the original — or null
picker.setCrop({ x: 0, y: 0, width: 400, height: 400 });
picker.setAspect(16 / 9);
picker.rotate(90); // or -90
picker.flip('x'); // or 'y'
picker.zoom(1.5);
picker.reset();
picker.clear();
picker.setOptions({ maxWidth: 256 });
picker.destroy(); // gives the page its own input back
picker.input; // the real <input type="file">
picker.element; // the widget root
getCrop() returns null until there is a picture and the widget has been laid out — so a
cropper built inside a closed modal says nothing rather than 0 × 0.
Events
picker.element.addEventListener('dx:crop', (event) => {
event.detail.crop; // { x, y, width, height } in source pixels
event.detail.width; // the output size, after maxWidth and friends
event.detail.height;
});
Words
createImageCropper(input, {
strings: {
label: 'أفلت صورة هنا',
hint: 'أو اخترها',
selection: 'منطقة القص',
zoom: 'تكبير',
rotateLeft: 'تدوير لليسار',
rotateRight: 'تدوير لليمين',
reset: 'إعادة',
remove: 'إزالة',
notAnImage: 'هذا ليس ملف صورة',
size: (w, h) => `${w} × ${h}`,
position: (x, y, w, h) => `${w} في ${h}، عند ${x}، ${y}`,
},
});
RTL needs nothing else: the layout is written in logical properties, so dir="rtl" mirrors it.
Updated 12 Sep 2026