Skip to content

[CropperJS] Edit the cropper image #2380

Open
@RehArk

Description

@RehArk

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' });
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    RFCRFC = Request For Comments (proposals about features that you want to be discussed)Stalled

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions