Adjust the size of the FabricJS canvas within a child component in VueJS

In my project, I am using VueJS and FabricJS to create a dynamic canvas that changes size based on user input. The goal is to have the canvas adjust its dimensions as soon as the user enters new values in the sidebar component.

Despite using $emit from child to parent components, I am facing an issue where the canvas size does not update as intended.

CustomSideBar.vue

<template>
     <div class="control-bar">
        <b-sidebar position="static" open >
           <b-menu-list>
               <b-menu-item label="Height">
                   <b-field>
                       <b-input v-model="height" maxlength="5" @change="emitHeight()"></b-input>
                   </b-field>
               </b-menu-item>
               <b-menu-item>
                   <b-field>
                       <b-input v-model="width" maxlength="5" @change="emitWidth()"></b-input>
                   </b-field>
               </b-menu-item>
           </b-menu-list>
        </b-sidebar>
     </div>
  </template>

  <script>
    export default {
      data() {
       return {
           width: '640',
           height: '480',
       }
      },
      methods: {
        emitWidth() {
           this.$emit('changeWidth', this.width)
        },
        emitHeight() {
           this.$emit('changeHeight', this.height)
        }
      },
    }
  </script>

CustomCanvas.vue

<template>
    <div class="columns">
        <section class="section canvas-section column auto">
            <CustomSideBar @changeWidth="widthChange($event)" @changeHeight="heightChange($event)" />
        </section>
        <section class="section canvas-section column is-10 canvas-column">
            <canvas class="canvas" ref="can"></canvas>
        </section>
    </div>
</template>

<script>
import {fabric } from 'fabric'
import CustomSideBar from '../components/CustomSideBar.vue'

export default {
    data() {
        return {
            canvasHeight: '480',
            canvasWidth: '640',
            canvas: null
        }
    },
    components: {
        CustomSideBar
    },
    methods: {
        heightChange (height) {
            this.canvasHeight = height;
            this.canvas.setHeight = this.canvasHeight;
        },
        widthChange (width) {
            this.canvasWidth = width;
            this.canvas.setWidth = this.canvasWidth;
        }
    },
    mounted() {
        const ref = this.$refs.can;
        this.canvas = new fabric.Canvas(ref);
    }
    
}
</script>

<style scoped>
    .canvas-column {
        width: 100%;
        height: 100%;
        background-color: lightgrey;
        text-align: center;
    }
    .canvas {
        border: 1px solid darkgrey;
        margin-left: auto;
        margin-right: auto;
    }
    .canvas-section {
        padding: 0;
    }
</style>

Answer №1

adjustCanvasHeight (newHeight) {
    this.canvasHeight = newHeight;
    this.canvas.setHeight(this.canvasHeight);
},
modifyCanvasWidth (newWidth) {
    this.canvasWidth = newWidth;
    this.canvas.setWidth(this.canvasWidth);
}

Instead of directly assigning properties, utilize the setHeight and setWidth methods. This way, parameters can be passed into these methods for a more dynamic approach.

this.canvas.setHeight(this.canvasHeight);
this.canvas.setWidth(this.canvasWidth);

Try it out on Codesandbox: https://codesandbox.io/s/fabric-js-stackoverflow-problem-4g4x2

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

Preventing users from inputting the same number more than once

Here are a series of text input fields pertaining to a single question: <input type="text" name="{{ $answer->id }}" value="" style="width:20px; text-align:center" maxlength="1" oninput="this.value=this.value.replace(/[^0-5]/g,'');" /> & ...

What is the method for executing code in HTML without needing a beginning or ending tag?

I have created a code that creates a shape which alternates between the colors green and blue, along with changing text from 'Hi' to 'Hello' when a button is clicked. Now, I am looking for a way to make this transition happen automatica ...

After upgrading from Vuetify version 1.5 to 2.0.18, an issue arises with modules not being found

I encountered the following error: module not found error To address this issue, I took the following steps: Commented out import 'vuetify/src/stylus/main.styl' in the src/plugins/vuetify.js file. Added import 'vuetify/src/styles/main. ...

Swap the text within the curly braces with the div element containing the specified text

I have an input and a textarea. Using Vue, I am currently setting the textarea's text to match what's in the input field. However, now I want to be able to change the color of specific text by typing something like {#123123}text{/#}. At this poin ...

Creating bidirectional binding between a Vue.js instance and a custom native web component: A step-by-step guide

Here is an example showcasing a custom web component called my-input. The goal is to establish a binding between the value attribute of this custom input component and the email attribute of a Vue instance. (Please note that this example may require Chrome ...

"Exploring the world of custom middleware in NextJs on a localhost

Question regarding nextjs page middleware: the documentation states that the request object should include geo, IP, ua, cookies, and nexturl properties. Visit the link for more information. I am attempting to retrieve the user's location using page m ...

"Customized color selection based on conditions using Angular's UI-Grid

I'm trying to create conditional coloring in my grid based on the data, using the cellClass function in columnDefs. The issue I'm facing is that the classes are not updated when there is a selection change, preventing me from defining colors for ...

Concealing and revealing the triangular indicator within a bullet diagram using the AngularJS-nvd3-directives library

I am currently utilizing the nvd3-bullet-chart feature from the angularjs-nvd3-directives library in order to present maximum, current, and average data. To exclude the minimum variable from the array for display purposes, I have set its value to 0. In a ...

Real-time data feeds straight from JSON

Currently, I have a JSON file that is generated dynamically and it contains match information along with a unique id. This JSON data is categorized into live, upcoming, and recent arrays. Being new to Javascript, I am unsure about the best approach to crea ...

Executing an AngularJS function using regular JavaScript code

I am currently working with AngularJS and Typescript. I have integrated an external library into my project and now I need to call an AngularJS method from that library, which is written in vanilla JavaScript. I tried following this example, but unfortunat ...

Ways to showcase a JSON menu with a single level

I have a json file containing links to all the images in a specific folder, as shown below: ["http://img1.png","http://img2.png","http://img3.png","http://img4.png"] I would like to create a <ul> list using this data, but I'm not sure how to d ...

An alternative way to update the radio button's checkability status using the :checked or :unchecked attributes

Within the code snippet below, there are two radio buttons present. Initially, both of them are unchecked. When the first radio button is checked, the log message in change_() function prints "male". On the other hand, when the second radio button is check ...

Is it possible to capture and store server responses on the client side using Node.js and React Native?

Here's a POST request I have: router.post("/projects", async (req, res) => { const { projectName, projectDescription, projectBudget, projectDuration, industry, companyName, numberOfEmployees, diamond, } = req.bod ...

Showing attributes of models using Sequelize and Handlebars

As a novice in the world of programming, I am currently immersed in a website project where users can write and post articles. One crucial aspect I am focusing on is displaying the history of articles written by each user on their account page. Despite uti ...

Tips for importing several makeStyles in tss-react

When upgrading from MUI4 to MUI5 using tss-react, we encountered a problem with multiple styles imports in some files. const { classes } = GridStyles(); const { classes } = IntakeTableStyles(); const { classes } = CommonThemeStyles(); This resulted in ...

Developing an animated feature that displays a dynamic count up to the current size of the browser window

I have a script that's able to determine the height and width of my browser window. However, I am facing a challenge in creating a way for these dimensions to count up from zero to their current values upon loading. The desired functionality would be ...

Creating a feature in Angular JS that allows for each item in a list to be toggled individually

Looking for a more efficient way to toggle individual buttons without updating all at once? Check out this basic example where each button toggles independently by using ng-click="selected = !selected". Instead of updating all buttons at once, you can achi ...

Calling functions in AngularJS/HTML can help you execute specific

Just started with angularjs and facing some major issues haha... I have something that seems to be working fine, but I can't figure out what's wrong with this code... can someone please help me? Here it is: Basically, the scope.create function ...

JSON nested error: Cannot read property 'length' of undefined

Having some trouble working with a nested array within a JSON in D3JS, specifically encountering a "property length undefined" error at the line: .attr("d", function(d) { return line(d.points); }). Below is the JSON data structure: [ { "aspectRatio" ...

Generate the Xpath for the mentioned href element to use with Selenium Webdriver

I need help creating the Xpath for a specific href element using Selenium webdriver with only IE browser. The HTML code I am working with is as follows: I am looking to find the Xpath for: . Can someone assist in generating the correct Xpath expression ...