javascriptvue.jsantdcropperjscropper

how to destroy cropper.js properly so that next crop will get new image?


i have a vue app form that has an image uploader by ant-design-vue upload. i linked this image uploader to a new components that process the image to crop after upload by using cropper.js. for the first time crop everything were fine and worked perfectly. but when the user need to change the photo and crop again for the second time, the image on the crop area still using the first image. the third upload will crop the second area and next will received the same impact.

this is the structure of my code :

<template>
  <div>
    <a-row :gutter="16">
      <img ref="image" :src="initialImage">
    </a-row><br />
    <a-row :gutter="16">
      <a-button type="primary" style="float: right;" @click="crop">Crop</a-button>
      <a-button style="float: right; margin-right: 5px;" @click="cancel">Cancel</a-button>
    </a-row>
  </div>
</template>

and this is the script and style:

<script>
import Cropper from 'cropperjs';

export default {
  name: 'PostCropper',
  props: {
    uploadedImage: String,
  },
  data() {
    return {
      cropper: {},
      updatedImage: {},
      initialImage: this.uploadedImage,
    };
  },
  methods: {
    crop() {
      this.$emit('update-image', this.updatedImage);
    },
    cancel() {
      this.$emit('cancel-upload');
    },
    cropImage() {
      this.cropper = new Cropper(this.$refs.image, {
        autoCropArea: 1,
        cropBoxResizable: false,
        zoomOnTouch: true,
        zoomable: true,
        scalable: false,
        aspectRatio: 1,
        resizable: false,
        crop: () => {
          const canvas = this.cropper.getCroppedCanvas();
          this.updatedImage = canvas.toDataURL('image/png');
        },
      });
    },
  },
  watch: {
    uploadedImage() {
      this.cropper.destroy();
      this.initialImage = this.uploadedImage;
      this.cropImage();
    },
  },
  mounted() {
    this.cropImage();
  },
};
</script>

<style lang="scss">

.cropper-crop-box .cropper-view-box {
    border-radius:50%;
  }
</style>

the problem occur in here:

          this.cropper = new Cropper(this.$refs.image, {
            autoCropArea: 1,
            cropBoxResizable: false,
            zoomOnTouch: true,
            zoomable: true,
            scalable: false,
            aspectRatio: 1,
            resizable: false,
            crop: () => {
              const canvas = this.cropper.getCroppedCanvas();
              this.updatedImage = canvas.toDataURL('image/png');
            },
          });

where i have destroy the this.cropper but still crop the same image. i have tried to preview by console.log the every value for this.cropper, this.image, this.initialImage, this.uploadedImage but all of them worked with no problem. it will carry new value on this.uploadedImage is change by using vue watch. i don't know why only this function above still carry the same image. is there any way i could initialize back the this.cropper or maybe a way that can overcome my problem like rerender this child components?


Solution

  • i have another way which destroy the child component in parent component instead of destroy a variable. it's worked perfectly by using v-if method to destroy the imported components.