In Vue, the CropperJs image initially appears small, but it returns to its original size after editing

I encountered a peculiar issue while working on a website for image cropping using Vue.js and CropperJs. On the homepage, users can select an image to crop and proceed to the next page where a component named ImageCropper.vue is displayed. Strangely, the canvas appears tiny initially. However, when I made a slight modification to the HTML (such as adding a blank line), the image resized itself correctly.

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>

Original template view: https://i.stack.imgur.com/5woRw.png

Modified template view (after adding a blank line): https://i.stack.imgur.com/h6THB.png

I attempted to style it with CSS without success. Perhaps my Vue implementation has an issue? This project uses Vue with Vuetify components.

Answer №1

Encountered an issue where the cropper was initialized while its container was not visible due to the use of Vuetify's stepper. The cropping functionality only appeared after the user clicked on "continue", before which it had display: none. Upon editing, the cropper became visible and was re-initialized when its container was visible, resulting in normal rendering (using hot reloading with Vue CLI). Although I cannot pinpoint the exact cause of this behavior, I am confident it is not an error in my code. It is possible that Cropperjs and Vuetify's stepper may not be fully compatible. To resolve this, I added a `continueClicked` property to my Vuex state with a default value of false. I then attached a click listener to the initial Continue button to set `continueClicked` in Vuex to true. Finally, I used the directive v-if="continueClicked" in the ImageCropper.vue component like this:

<ImageCropper v-if="continueClicked" />
. This ensures that the cropper is rendered only when the Continue button is clicked and `continueClicked` is set to true, making it visible when its container is visible.

Answer №2

If you're looking for a solution, consider using the vue-cropperjs wrapper.

<template>
 <div>
   <vue-cropper ref="cropper" :src="imageSource" alt="Image Source"></vue-cropper>
   <v-btn @click="saveImage">Save</v-btn>
 </div>
</template>
<script>
  import VueCropper from 'vue-cropperjs';
  import 'cropperjs/dist/cropper.css';

  export default{
    name: "CroppingComponent",
    components: {
            VueCropper
    },
    data() {
      return {
        imageSource: ''
      }
    },
    methods: {
      saveImage: function(){
        this.$refs.cropper.getCroppedCanvas().toBlob((blob) => {

          //Do something with the blob, like attaching it to form data and sending it to the server
          const formData = new FormData();
          formData.append("type", "profile");
          formData.append('file', blob, this.fileName);

        });
      }
    }
  }
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilize Vue and Django to submit dynamic form data efficiently

Currently utilizing Vue.js to send data from a standard .html form to Django. My experience with Python and Django is relatively fresh, only a few days in. Within my form, there is a segment where users can dynamically input form fields (both regular inpu ...

What are the best tools to develop a browser-based 2D top-down soccer simulation?

I'm looking to create a 2D top-down soccer simulation game for web browsers using modern technologies and without the need for additional plugins like Flash or Silverlight, making it compatible with mobile devices as well. The game will be AI-controll ...

Combining a form and table on a single webpage, I am curious how to utilize the form to update the table effectively using Express and Node.js

Seeking guidance in website development as I face a particular challenge. I aim to create a dynamic search page for a website. The form should allow users to select a location or category, with the same page updating with relevant results. Despite succes ...

Dealing with multiple input fields that are generated using the map method in combination with react-redux

I am working on a project where I have a product list in JSON format stored in json-server. I am using React-Redux to fetch the data and render it in a table. Additionally, I have an input field where users can enter the quantity of each product. I need to ...

The Vue.js v-on:mouseover function is not functioning properly in displaying the menu

When I hover over a LI tag, I want to display a menu. I have successfully implemented it using a simple variable with the following code: @mouseover="hoverFormsControls=true" @mouseleave="hoverFormsControls=false" However, when I attempted to use an arr ...

What is preventing me from using JavaScript to generate labels?

My current project involves creating dynamic input fields to filter products by color. I initially attempted static checkbox inputs for this purpose, which worked fine. Now, I want to achieve the same functionality but dynamically through JavaScript. Inste ...

Tips for ensuring an animation is triggered only after Angular has fully initialized

Within this demonstration, the use of the dashOffset property initiates the animation for the dash-offset. For instance, upon entering a new percentage in the input field, the animation is activated. The code responsible for updating the dashOffset state ...

Display a loading image as a placeholder while the Block is loading on the Viewport

Despite my extensive search for a solution to my problem, I have been unable to find one that addresses it directly. I am trying to display a "loading" image for 4 seconds before the content of the div is loaded. Unfortunately, I haven't been able to ...

Vanilla JavaScript MVC - Send notification to controller from model upon successful AJAX completion

I am facing some challenges with my first vanilla JS MVC app. When my model sends an AJAX request to the server, the controller updates the view before waiting for the promise to resolve, resulting in an empty update on the view. How can I inform the contr ...

Using Javascript to create bold text within a string

I have noticed that many people are asking about this issue, but it seems like a clear and simple answer is hard to come by. Currently, I am working with Vue and trying to display text from an object in a component. My goal is to highlight the price port ...

Angular2 - Implementing Form Validation for Dynamically Generated Input Fields Based on Conditions

My goal is to create a basic form that allows users to select between two options: Local and Foreigner. If the user does not make a selection, the form should be marked as invalid. Choosing Local will make the form valid, while selecting Foreigner will rev ...

Is there a glitch in the console when sorting an array of dates?

I'm puzzled by the fact that the console is displaying a sorted array in both logs. It doesn't make sense to me because it should not be sorted at the first log, right? static reloadAndSortItems() { let array = []; const items = Store. ...

What is the best method for eliminating script tags from a Magento web store's source code?

Below is the source code for the Magento site's homepage. I am looking to eliminate all JavaScript links from the code: ...

Getting the input tag id of an HTML form can be achieved by using the "id

<?php $i = 1; $query1 = mysql_query("SELECT * FROM `alert_history` ORDER BY `alert_history`.`id` DESC LIMIT ".$start.",".$per_page.""); while($result = mysql_fetch_array($query1)){ echo '<td colspan = "2">& ...

What is causing the 'transitionend' event to trigger multiple times?

Currently, I'm honing my JavaScript skills by taking on the 30 days of JavaScript challenge. I'm puzzled by why the 'transitioned' event is triggered twice in the code snippet below. My CSS only contains one property called transform, ...

What could be the reason behind npm trying to utilize a package version that is not specified in my package.json file?

My Angular and .NET 5 web application is encountering an issue when trying to install packages using the command npm i. The error message that appears is: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While re ...

Incorporating a jQuery word count and limit within PHP code: a step-by-step guide

I am encountering an issue with a textarea count code. It functions perfectly on its own but when I integrate it as shown below, it stops working without throwing any errors. I have been trying to resolve this for more than 3 days now. Any assistance would ...

The socket.io.js file could not be located while using (nodejs with express [4.13] and socket.io [1.3])

Currently, I am utilizing express 4.13 and socket.io 1.3.2 along with an express generator. Here is the code snippet from my app.js: var app = express(); var server=require('http').createServer(app).listen(app.get('port'),'127.0. ...

Is there a way for me to access a user control property directly from the client side?

I'm in the process of developing several user controls that will be derived from my base class, BaseControl, which is a subclass of UserControl. The BaseControl class contains important features that I will need to utilize, including a string property ...

Leveraging mdbvue within the SAFE Network, style elements are noticeable by their absence

I checked out this handy tutorial But what really caught my attention was this tutorial: After following along, I ended up with the result below: It's clear that something is missing in terms of style. As a novice in Vue and still getting familiar ...