I am using the ngx-image-cropper library for cropping images in my Angular 8 project.
What I want to do is:
- I want to show the cropper inside a modal on selecting a file.
- The modal has a crop button on clicking which the image will be cropped (no autocrop) and a cancel button which can be used to close the modal without cropping the image.
- After the image is cropped, the modal will be closed and there will be an edit button which can be used to recrop the image (On clicking crop, I essentially crop the image and hide the modal. So on clicking edit, I just show the hidden modal again.).
- If another file is selected from the file input, the modal will be shown with the new image. The user can either crop or cancel. If it is cancelled, I want to reset the source image of the cropper to the previous image. How can I do that?
I have tried the following, but doesn't work:
lastCropperPosition: CropperPosition;
lastCroppedImage: any;
crop() {
this.imageCropper.crop();
this.lastCropperPosition = this.getCurrentCropperPosition();
this.lastCroppedImage = new ElementRef(
this.imageCropper.sourceImage.nativeElement
);
this.logoModal.hide();
}
cancelCrop() {
if (this.lastCroppedImage) {
this.imageCropper.sourceImage = this.lastCroppedImage;
}
if (this.lastCropperPosition) {
this.imageCropper.cropper = this.getLastCropperPosition();
}
this.logoModal.hide();
}
getCurrentCropperPosition() {
return {
x1: this.imageCropper.cropper.x1,
x2: this.imageCropper.cropper.x2,
y1: this.imageCropper.cropper.y1,
y2: this.imageCropper.cropper.y2
};
}
getLastCropperPosition() {
return {
x1: this.lastCropperPosition.x1,
x2: this.lastCropperPosition.x2,
y1: this.lastCropperPosition.y1,
y2: this.lastCropperPosition.y2
};
}
HTML Code:
<div bsModal #logoModal="bs-modal" class="modal fade" tabindex="-1"
role="dialog" aria-labelledby="logoModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Crop Image</h4>
</div>
<div class="modal-body">
<image-cropper
[imageChangedEvent]="imageChangedEvent"
[maintainAspectRatio]="true"
[aspectRatio]="rules.logo.maxWidth / rules.logo.maxHeight"
[cropperMinWidth]="rules.logo.minWidth"
[resizeToWidth]="rules.logo.maxWidth"
[autoCrop]="false"
onlyScaleDown="true"
outputType="both"
(imageCropped)="imageCropped($event)"
(imageLoaded)="imageLoaded()"
(cropperReady)="cropperReady()"
(loadImageFailed)="loadImageFailed()"></image-cropper>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-secondary"
(click)="cancelCrop()">Cancel</button>
<button type="button" class="btn btn-sm btn-primary"
(click)="crop()">Crop</button>
</div>
</div>
</div>
</div>
Is using the sourceImage
property the right way to do what I want to do? I change the this.lastCroppedImage
only inside crop() method. But it seems to be changing whenever a new image is selected in the file input. Why does that happen?
PS: I have already tried assigning the sourceImage
directly without creating a new ElementRef
. That doesn't work either.
Stackblitz example: https://stackblitz.com/edit/image-cropper-r5pyqh
Steps to reproduce in Stackblitz:
Browse and crop an image.
Browse again and select new image.
Click cancel in the crop window.
Click recrop. Observe that the image in crop window is the second one. Instead I want the first one.