fengyuanchen / cropperjs

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

Coordinates not being respected when initilized #1177

Closed htodep closed 5 months ago

htodep commented 6 months ago

Describe the bug When I change an image via the cropper, coordinates that I give to the function are not respected and the wrong crop area is shown.

This is my function

function initImageCropper(targetId){
var cropX = document.getElementById('CropX');
var cropY = document.getElementById('CropY');
var cropWidth = document.getElementById('CropWidth');
var cropHeight = document.getElementById('CropHeight');
var rotate = document.getElementById('Rotate');

console.log('init',cropX.value, cropY.value, cropWidth.value, cropHeight.value, rotate.value)

var image = document.getElementById(targetId);

var cropper = new Cropper(image, {
    aspectRatio: 4 / 3,
    autoCrop: true,
    viewMode:3,
    autoCropArea: 1,
    getData: true,
    zoomable: false,
    data: { "x": parseInt(cropX.value), "y": parseInt(cropY.value), "width": parseInt(cropWidth.value), "height": parseInt(cropHeight.value), "rotate": parseInt(rotate.value) },
    crop: function (e) {
        var data = e.detail;
        cropX.value = Math.round(data.x);
        cropY.value = Math.round(data.y);
        cropWidth.value = Math.round(data.width);
        cropHeight.value = Math.round(data.height);
        rotate.value = typeof data.rotate !== 'undefined' ? data.rotate : '';

        console.log('crop', cropX.value, cropY.value, cropWidth.value, cropHeight.value, rotate.value)
    }
});
}

Get the coordinates from hidden input fields. set "data" values from these hidden inputs. And if the crop moves or of its rotated I call the crop method and replace the values in the hidden inputs.

The crop method is being called before the ready, so I tried to use the ready function to set the SetData but it didn't work.

These are the values I get when I try to log the values:

These don't match and I don't know why.

So the image that is saved looks like this: image

But the image that is shown with cropbox looks like this: image

This is the original image: image

What am I doing wrong here?

fengyuanchen commented 5 months ago

For restore a selection, please reference this example: https://fengyuanchen.github.io/cropperjs/examples/cropper-in-modal.html

htodep commented 5 months ago

So if i understand correctly I also need to store/save the CanvasData for every image so I can restore when editing the image? And also use the setData to show the rotate correctly? Without the setData it doesn't show the rotate setting

    var cropX = document.getElementById('CropX');
    var cropY = document.getElementById('CropY');
    var cropWidth = document.getElementById('CropWidth');
    var cropHeight = document.getElementById('CropHeight');
    var rotate = document.getElementById('Rotate');
    var cropBoxData = { left: parseInt(cropX.value), top: parseInt(cropY.value), width: parseInt(cropWidth.value), height: parseInt(cropHeight.value), rotate: parseInt(rotate.value) };
    var canvasData = { "left": -126.33333333333337, "top": -384, "width": 640, "height": 1024, "naturalWidth": 640, "naturalHeight": 1024 };

    var image = document.getElementById(targetId);

    var cropper = new Cropper(image, {
        aspectRatio: 4 / 3,
        autoCrop: true,
        viewMode:2,
        autoCropArea: 1,
        getData: true,
        zoomable: false,
        data: { "x": parseInt(cropX.value), "y": parseInt(cropY.value), "width": parseInt(cropWidth.value), "height": parseInt(cropHeight.value), "rotate": parseInt(rotate.value) },

        ready: function () {
            cropper.setCropBoxData(cropBoxData).setCanvasData(canvasData);
        },

        crop: function (e) {
            var data = e.detail;
            cropX.value = Math.round(data.x);
            cropY.value = Math.round(data.y);
            cropWidth.value = Math.round(data.width);
            cropHeight.value = Math.round(data.height);
            rotate.value = typeof data.rotate !== 'undefined' ? data.rotate : '';
        }
    });
fengyuanchen commented 5 months ago

To restore the canvas and crop box exactly, you must save both the canvasData and cropBoxData, and use them by calling setCanvasData and setCropBoxData.

Why?

In short:

htodep commented 4 months ago

@fengyuanchen Isn't there any other option? I don't want to store the canvas data for every image(can be millions...). Is there an option to adjust the canvas if the image gets rotated? So I don't need to move the canvas. Example: image normal view

image rotated

Instead of this when rotated: image

fengyuanchen commented 4 months ago

Try v2.x?