fengyuanchen / cropperjs

JavaScript image cropper.
https://fengyuanchen.github.io/cropperjs/
MIT License
13.01k stars 2.4k forks source link

Zoomin and Zoomout with Slider #858

Closed jawad-aziz-farhad closed 3 years ago

jawad-aziz-farhad commented 3 years ago

I'm trying to achieve Zoomin and Zoomout functionality with slider (range input). Zoomin works fine with both wheelzoom and slider. For zoomout, with wheelzoom it goes till it reaches cropbox and then stop, we want to achieve the exact same behavior with slider and for that we should know the min attribute of input range. How can we calculate the min zoom ratio for a crop box of 400*400, so we can set the min attribute to slider.

MithileshHinge commented 3 years ago

Here's a snippet from my attempt at making a slider:

const {
    width,
    height,
    naturalWidth,
    naturalHeight,
} = cropper.getImageData();
const isLandscape = (width >= height);
let zoomMin = (width / naturalWidth);
if (isLandscape) {
    zoomMin = (height / naturalHeight);
}

Hope it helps :)

fengyuanchen commented 3 years ago

@jawad-aziz-farhad Have you set the viewMode option to 0?

jawad-aziz-farhad commented 3 years ago

Hey @fengyuanchen , viewMode is set to 1

jawad-aziz-farhad commented 3 years ago

Please have a look at this codesandbox, It might help you identifying the issue.

fengyuanchen commented 3 years ago

@jawad-aziz-farhad Try this for computing the min zoom ratio:

const containerData = cropper.getContainerData();
const canvasData = cropper.getCanvasData();
const minRatio = containerData.height / canvasData.naturalHeight;
jawad-aziz-farhad commented 3 years ago

@fengyuanchen I applied above snippet but it's not working. Have you checked it at your end ?

jawad-aziz-farhad commented 3 years ago

Please have a look at this video I explained the issue. Thanks

fengyuanchen commented 3 years ago

@jawad-aziz-farhad It seems the zoomMinVal does not updated.

// ..
console.log(minRatio); // > 1
setZoomMinVal(minRatio);
console.log(zoomMinVal);  // > 0
// ...
fengyuanchen commented 3 years ago
zoom: function (e) {
  console.log(zoomMinVal, zoomMaxVal);

  // zoom in
  if (e.detail.ratio > e.detail.oldRatio) {
    if (e.detail.ratio > zoomMaxVal) {
      e.preventDefault();
      this.cropper.zoomTo(zoomMaxVal);
      setZoomVal(zoomMaxVal);
    }

  // zoom out
  } else if (e.detail.ratio < e.detail.oldRatio) {
    if (e.detail.ratio < zoomMinVal) {
      e.preventDefault();
      this.cropper.zoomTo(zoomMinVal);
      setZoomVal(zoomMinVal);
    }
  }
},
jawad-aziz-farhad commented 3 years ago

@jawad-aziz-farhad It seems the zoomMinVal does not updated.

// ..
console.log(minRatio); // > 1
setZoomMinVal(minRatio);
console.log(zoomMinVal);  // > 0
// ...

It's because of the asynchronous nature of setState.

jawad-aziz-farhad commented 3 years ago

It's still not working Specially for Zoomout. On Zoomout, It never takes image to the cropbox dimensions with slider as it does with wheelzoom. Issue which I figured out is in zoom function,

zoom: function (e) {
  console.log(zoomMinVal, zoomMaxVal);

  // zoom in
  if (e.detail.ratio > e.detail.oldRatio) {
    if (e.detail.ratio > zoomMaxVal) {
      e.preventDefault();
      this.cropper.zoomTo(zoomMaxVal);
      setZoomVal(zoomMaxVal);
    }

  // zoom out
  } else if (e.detail.ratio < e.detail.oldRatio) {
    if (e.detail.ratio < zoomMinVal) {
      e.preventDefault();
      this.cropper.zoomTo(zoomMinVal);
      setZoomVal(zoomMinVal);
    }
  }
},

In above snippet, zoomMaxVal will always be the initial value and not updated, We are updating it in the ready function like you suggested:

        const containerData = this.cropper.getContainerData();
        const canvasData = this.cropper.getCanvasData();
        const minRatio = containerData.height / canvasData.naturalHeight;
        setZoomMinVal(minRatio);  // Min Value
        setZoomMaxVal(minRatio * 2); // Multiplying Min Value with 2

but It seems like zoom function still using the initial value. Codesanbox is updated with your suggestions.

fengyuanchen commented 3 years ago

It is not an issue of the Cropper.js itself, man.