Search code examples
javascriptvue.jsvuetify.jscropperjs

CropperJs image is tiny in Vue but after editing it gets back to normal size


This is a very strange behavior and I don't know what to make of it, I'm building a website for cropping images using Vue.js and CropperJs, on homepage users select the image they want to crop and click on 'Continue', next page shows a component called ImageCropper.vue, the canvas and everything is displayed successfully but it's tiny, but let's say I edit the html, even if I add just a blank line, the image gets back to the size it should be (I don't have a predefined size for it, so it just takes 100% of the width of the container and height is auto, I suppose.)

ImageCropper.vue

<template>
    <div class="image-container">
        <img ref="image" :src="source">

    </div>
</template>

<script>
import Cropper from 'cropperjs'

export default {
    name: "ImageCropper",
    props: ["source"],

    data() {
        return {
            cropper: null,
            imageElement: null
        }
    },

    mounted() {
        this.imageElement = this.$refs.image
        this.cropper = new Cropper(this.imageElement, {
                aspectRatio: 1 
        })

    }
}
</script>

Before editing template: before editing

After editing it (just added a blank line): enter image description here

I tried styling it with css but none seem to have effect on it, maybe there's something wrong with the way I use vue? This is Vue with Vuetify, if that matters.


Solution

  • The issue was that cropper got initialized while its container was not visible, as I was using vuetify's stepper, the cropping part came after user clicked on "continue", before that is had display: none, when I edited it though, it was visible and cropper was being re-initialized whilst its container was visible thus resulting in it rendering normally (Hot reloading with vue cli). I don't know what exactly is the cause of this but I am pretty certain it's not coding error on my side, maybe cropperjs and vuetify's stepper don't work well together. I solved it by adding continueClicked to my Vuex state and set default to false, then added @click listener to initial Continue button which sets the continueClicked in Vuex to true, added v-if="continueClicked" directive to the ImageCropper.vue component, like so: <ImageCropper v-if="continueClicked" />, this way when the Continue button is clicked and continueClicked is set to true, cropper gets rendered when its container is visible.