David Kimura PRO said almost 3 years ago on Cropping Active Storage Uploads :
You might be able to capture some of the functionality with editing an existing image with something like this. You need to let the stimulus controller know that there is an existing image, so on the cropper controller, an additional value was added "existing". We set this value in the view where we are initializing the stimulus controller.  However, it does seem a bit buggy, but this should hopefully help you move forward with this feature.

--- a/app/javascript/controllers/cropper_controller.js
+++ b/app/javascript/controllers/cropper_controller.js
@@ -4,11 +4,20 @@ import "cropperjs/dist/cropper.css"
 
 export default class extends Controller {
   static targets = ["image"]
-  static values = { model: String }
+  static values = { model: String, existing: String }
+
+  connect() {
+    if (this.existingValue == "true") {
+      this.changed()
+    }
+  }
 
   changed() {
     let _this = this
-    new Cropper(this.imageTarget, {
+    if (this.cropper != undefined) {
+      this.cropper.destroy()
+    }
+    this.cropper = new Cropper(this.imageTarget, {
       crop(event) {
         _this.crop_x().value = event.detail.x
         _this.crop_y().value = event.detail.y
diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb
index 9e73386..c4fb40a 100644
--- a/app/views/users/_form.html.erb
+++ b/app/views/users/_form.html.erb
@@ -17,9 +17,9 @@
   <div class="field"
        data-controller='instant-upload cropper'
        data-cropper-model-value='user'
+       data-cropper-existing-value="<%= @user.avatar.attached? %>"
       data-instant-upload-token-value="<%= direct_upload_token("User#avatar") %>"
-      data-instant-upload-attachment-value='User#avatar'
-      >
+      data-instant-upload-attachment-value='User#avatar'>
     <%= form.label :avatar %>
     <%= form.file_field :avatar,
           'data-instant-upload-target': 'input',