DEV Community

Faith Morante
Faith Morante

Posted on

Rotating a vertical rectangle image using React-cropper

For those who are using react-cropper package (https://github.com/react-cropper/react-cropper/), and has issues with rotating images, you're reading the correct post.

react-cropper uses cropperjs under the hood. And cropperjs has multiple github issues regarding auto-fit issues when rotating.

Here's the modal we use with the image inside the Cropper

Image description

After rotating, the image goes out of bounds and looks cropped out. I played around with setCropBoxData and setCanvasData and nothing worked. Until I came to find out that this is more like a scaling problem.

I created a helper function to handle scaling for these types of images.

/**
   * This function scales the image when a vertical rectangle image is being rotated.
   * The goal is to auto fit the image inside the container width.
   */
  const handleScaleVerticalImg = (cropperRef) => {
    const imgData = cropperRef.current.cropper.getImageData();
    const containerData = cropperRef.current.cropper.getContainerData();
    const isVertImg = imgData?.naturalWidth < imgData?.naturalHeight;

    if (isVertImg && [90, 270, -90, -270].includes(imgData?.rotate)) {
      const height =
        imgData?.height < imgData?.naturalHeight
          ? imgData?.height
          : imgData?.naturalHeight;

      // img height is it's width after rotating
      cropperRef.current.cropper.scale(containerData.width / height);
    } else {
      cropperRef.current.cropper.scale(1);
    }
  };
Enter fullscreen mode Exit fullscreen mode

Breakdown of code:

if (isVertImg && [90, 270, -90, -270].includes(imgData?.rotate)) {
Enter fullscreen mode Exit fullscreen mode

This checks if the image is vertical and is rotated sideways.

const height =
        imgData?.height < imgData?.naturalHeight
          ? imgData?.height
          : imgData?.naturalHeight;
Enter fullscreen mode Exit fullscreen mode

imgData?.height is the container height, and we should get the smallest from these two. This is to ensure that when it rotates, the scale is calculated correctly.

cropperRef.current.cropper.scale(containerData.width / height);
Enter fullscreen mode Exit fullscreen mode

The image's width should scale down according to the container's width. In this case we are basing the image width from the height as when it rotates sideways, the height becomes the width.

After rotating, this is now what happens:

Image description

That's it, if you have any questions feel free to comment below!

Cheers,
FM

Top comments (1)

Collapse
 
thilakmani profile image
Thilakmani

can i get the github or fiddle link, to understand it better