How to enforce a fixed aspect ratio using CropperJS?

Hi everyone,

I'm trying to enforce a fixed 4:3 aspect ratio on image uploads using the built-in cropper in PHPMaker 2026. My goal is to allow resizing but always maintain this fixed ratio — and ideally apply it globally or at least to specific fields.

So far, here’s what I’ve tried:

  1. Enabled ImageCropper = true for my field in Page_Load() (also tested project wide by enabling it in Advanced Settings):

    $this->my_image_filename->ImageCropper = true;
    
  2. Attempted to configure the aspect ratio using JavaScript via:

    ew.imageCropperOptions["x_my_image_filename"] = { aspectRatio: 4 / 3, ... };
    

    But ew.imageCropperOptions appears to be undefined or never initialized, even after delaying with setTimeout.

  3. Tried intercepting the cropper setup using:

    $(document).on("image-cropper", function (e, args) {
        args.options.aspectRatio = 4 / 3;
    });
    

    But this event never seems to fire.

  4. Finally, I patched ew.initCropper directly:

    const originalInitCropper = ew.initCropper;
    ew.initCropper = function (elem, options) {
        if (elem?.id === "x_my_image_filename") {
            options.aspectRatio = 4 / 3;
        }
        return originalInitCropper.call(this, elem, options);
    };
    

    This executes, but has no visible effect on the cropper.


Despite trying multiple approaches (direct options, event hooks, monkey-patching), none of them seem to apply the 4:3 constraint. Is there an officially supported way to customize the cropper behavior in PHPMaker 2026? Or am I missing something fundamental?

Any guidance is appreciated — thanks in advance!


Let me know if you want to include additional technical details or screenshots.

You were trying your luck, but:

  1. There is no such property as ew.imageCropperOptions or ew.initCropper.
  2. There is no such event as "image-cropper".

However, there is ew.uploadOptions.cropperOptions:

    uploadOptions: { // See https://github.com/blueimp/jQuery-File-Upload/wiki/Options
        cropperOptions: { // See https://github.com/fengyuanchen/cropperjs/blob/e969348d313dafe3416926125b21388cc67cefb1/README.md#options
            autoCropArea: 1, // Define the automatic cropping area size (between 0 and 1)
            viewMode: 2 // Restrict the minimum canvas size to fit within the container
        },
    },

You may try to change it by Page_Head server event (see example 4).

1 Like

Awesome! :heart_eyes: Is working perfectly! Thank you very much! Your advice always guides us in the right direction!

However, when configured in the Page_Head section, the behavior is applied to all croppers (at the project level). I'd like to go a step further and ask if it would be possible to implement this at the field level as well? This would offer greater flexibility to configure the project with different AR formats if needed (for example, square format for avatars and 16:9 for other horizontal images).

From the source in ew.js:

// Original code
$("#ew-cropper-dialog").on("shown.bs.modal", function () {
          $dlg.data("cropper", new Cropper(this.querySelector("#ew-crop-image"), options.cropperOptions));
}).

So you can use the same "shown.bs.modal" event (e.g. by the page's Startup Script) to change the cropper, e.g.

$("#ew-cropper-dialog").on("shown.bs.modal", function () {
          $dlg.data("cropper", new Cropper(this.querySelector("#ew-crop-image"), {... your options...}));
}); // Replace the original cropper
1 Like

Awesome! Thank you for enlighten the way.

To make things a little easier for those who don't have the opportunity to be part of this wonderful community and are trying to find the solution only through search engines or AI advice (which helps but needs to be trained with something that works so it can generate valid solutions), here's a summary of my working solution.

Lock the Aspect Ratio at the project level:

<script <?= Nonce() ?>>
// Server Events > Global > All Pages > Page_Head
    // Lock Cropper's Aspect Ratio at the project level (eg. 16/9)
    ew.uploadOptions.cropperOptions.initialAspectRatio = 16/9;
    ew.uploadOptions.cropperOptions.aspectRatio = 16/9;
</script>

If needed to lock the Aspect Ratio only at the page level (to define it if not defined at the project level or override it for specific needs):

// Server Events > Client Scripts > Table-Specific > Add/Copy Page (or Edit Page…) > Startup Script

// Write your table-specific startup script here, no need to add script tags.
// Lock squared Aspect Ratio for editing Avatar images
ew.uploadOptions.cropperOptions.initialAspectRatio = 1/1;
ew.uploadOptions.cropperOptions.aspectRatio = 1/1;

If the Aspect Ratio is defined at the project level and there is a need to unlock it at the page level for specific cases:

// Server Events > Client Scripts > Table-Specific > Add/Copy Page (or Edit Page…) > Startup Script

// Write your table-specific startup script here, no need to add script tags.
// Lock squared Aspect Ratio for editing Avatar images
ew.uploadOptions.cropperOptions.initialAspectRatio = undefined;
ew.uploadOptions.cropperOptions.aspectRatio = undefined;

Good luck to everyone!

When using the cropper, the window has two buttons: Crop and Omit. I noticed that if the user omits the crop, the image is saved with the original aspect ratio. This means the cropper's implemented aspect ratio definition can be bypassed, resulting in a distorted image (eg. if the frontend enforces a 1:1 aspect ratio and the image is saved in 4:3), breaking the frontend's appearance, or displaying an incomplete image.

Is it possible to prevent this behavior and force the user to save the image with the aspect ratio defined in the cropper to avoid undesired effects?

If the user omit the cropping, there is no cropping at all, it is not that the cropper's aspect ratio being bypassed.

In that case you may do server size resizing and cropping, you may use Row_Inserting/Updating server event, you can get the image object by: (v2026)

$image = $this->MyField->Upload->getTempThumb(); // Assume single file upload

Note that you don't know if client side cropping is done or omitted. You need to check the image size yourself first, read Meta information.

If cropping is required, you can using the image object method to resize/crop, read Resizing Image, then you can save back the image to the field by:

$this->MyField->Upload->Value = (string) $image->toPng();

Read Cast Encoded Image Data to String.