react-image-crop icon indicating copy to clipboard operation
react-image-crop copied to clipboard

Possibility for variable aspect ratio locking (i.e. min + max aspect ratio)?

Open lostpebble opened this issue 6 years ago • 6 comments

Hi there, thanks so much for this library! Just threw it into a project and got up and running nice and easily (just had to tweak some CSS things to ensure vertical images don't overflow the cropping area).

I have a use case I'd like to implement somehow. For example, I want to allow people to add poster images to my app - in this case, a poster can be of multiple sizes, as some countries / cinemas choose to use a slightly different aspect ratio for their posters. It's not major differences, but the differences do exist. I'd like to allow cropping between the minimum aspect ratio and the maximum aspect ratio within those sizes.

My aspect ratios might look like this:

  {
    minAspect: 0.66,
    maxAspect: 0.75,
  }

I think this is not currently possible with react-image-crop. Is this something you think could be implemented? I'm happy to try take a look at it myself as well and make a PR.

lostpebble avatar Sep 23 '19 08:09 lostpebble

Hi and thanks, the height overflow thing was being contained with max-height fill-available but this was causing some worse problems so I removed it.

It sounds like you could calculate the width and height of the smaller aspect and the larger, and set minHeight + minWidth and maxHeight + maxWidth?

dominictobias avatar Sep 23 '19 18:09 dominictobias

Hi and thanks, the height overflow thing was being contained with max-height fill-available but this was causing some worse problems so I removed it.

Understandable. CSS can be a really unintuitive sometimes, especially with laying out image stuff.

It sounds like you could calculate the width and height of the smaller aspect and the larger, and set minHeight + minWidth and maxHeight + maxWidth?

I see. Wouldn't that perhaps still allow a range of unwanted aspect ratios? Since we're not restricting the ratio, but only the dimensions - in pixels. I do think this solution could work if we look at the original image and not allow it to become any taller or any wider based on the original dimensions and the wanted aspect ratio with minHeight + minWidth and maxHeight + maxWidth.

The issue then would be that the crop is restricted based on the original image's width or height, instead of being as small or as large as it needs to be inside of any sized image.

lostpebble avatar Sep 23 '19 21:09 lostpebble

Any updates?

Sebastp avatar Mar 06 '20 20:03 Sebastp

I was able to get this working by changing my onChange to this:

const onChange = (c, percentCrop) => {
   const newCrop = crop.unit === '%' ? percentCrop : c;
    if (!maxAspect || !minAspect) setCrop(newCrop);
    else if (c.width / c.height > maxAspect) {
      setCrop({ ...newCrop, height: newCrop.width / maxAspect });
    } else if (newCrop.width / newCrop.height < minAspect) {
      setCrop({ ...newCrop, height: newCrop.width / minAspect });
    } else setCrop(newCrop);
  };

samstanding avatar Oct 01 '20 14:10 samstanding

I was able to get this working by changing my onChange to this:

const onChange = (c, percentCrop) => {
   const newCrop = crop.unit === '%' ? percentCrop : c;
    if (!maxAspect || !minAspect) setCrop(newCrop);
    else if (c.width / c.height > maxAspect) {
      setCrop({ ...newCrop, height: newCrop.width / maxAspect });
    } else if (newCrop.width / newCrop.height < minAspect) {
      setCrop({ ...newCrop, height: newCrop.width / minAspect });
    } else setCrop(newCrop);
  };

Cool maybe I'll incorporate this logic

dominictobias avatar Oct 05 '20 11:10 dominictobias

I was able to get this working by changing my onChange to this:

const onChange = (c, percentCrop) => {
   const newCrop = crop.unit === '%' ? percentCrop : c;
    if (!maxAspect || !minAspect) setCrop(newCrop);
    else if (c.width / c.height > maxAspect) {
      setCrop({ ...newCrop, height: newCrop.width / maxAspect });
    } else if (newCrop.width / newCrop.height < minAspect) {
      setCrop({ ...newCrop, height: newCrop.width / minAspect });
    } else setCrop(newCrop);
  };

Hi there! This won't work because your crop may overflow the original image, you have to compare crop size with the image size

D0HaTeJIJI0 avatar Dec 13 '21 12:12 D0HaTeJIJI0