Open
Description
Hi everyone, I need to crop my image based on my file input, but the cropper is not allowing me to edit the image. I want to know if it is possible to do something like this to update the cropper:
import { Controller } from '@hotwired/stimulus';
import Cropper from 'cropperjs';
import CropEvent = Cropper.CropEvent;
export default class CropperController extends Controller {
declare readonly publicUrlValue: string;
declare readonly optionsValue: object;
declare img: HTMLImageElement;
declare cropper: Cropper;
static values = {
publicUrl: String,
options: Object,
img: HTMLImageElement,
cropper: Cropper
};
connect() {
this.initializeCropper();
}
initializeCropper() {
// Remove any existing cropper image and instance before initializing
if (this.img) {
this.img.remove();
}
if (this.cropper) {
this.cropper.destroy();
}
// Create image view
this.img = document.createElement('img');
this.img.classList.add('cropperjs-image');
this.img.src = this.publicUrlValue; // The current image URL value
const parent = this.element.parentNode;
if (!parent) {
throw new Error('Missing parent node for Cropperjs');
}
parent.appendChild(this.img);
// Options for the cropper instance
const options = this.optionsValue;
// Dispatch pre-connect event
this.dispatchEvent('pre-connect', { options, img: this.img });
// Build the cropper with the given image and options
this.cropper = new Cropper(this.img, options);
// Event listener to update the input value on crop
this.img.addEventListener('crop', (event) => {
(this.element as HTMLInputElement).value = JSON.stringify((event as CropEvent).detail);
});
// Dispatch connect event
this.dispatchEvent('connect', { cropper: this.cropper, options, img: this.img });
}
// Method to update the image URL and reinitialize the cropper
updateImage(newImageUrl) {
this.img.src = newImageUrl; // Update the public URL value
this.initializeCropper(); // Reinitialize the cropper with the new image
}
disconnect() {
if (this.cropper) {
this.cropper.destroy();
}
if (this.img) {
this.img.remove();
}
}
// Helper method to dispatch events
private dispatchEvent(name: string, payload: any) {
this.dispatch(name, { detail: payload, prefix: 'cropperjs' });
}
}