Interactive Vue.js canvases that adapt and respond to various

I am currently working on adjusting my canvas to fit within its container in a Vue component. When I call resizeCanvas() in the mounted hook, I notice that the container's height and width are both 0. How can I create a canvas that dynamically fits its container so that changes in the container size using CSS will automatically update the canvas? (Please excuse any language errors as English is not my first language)

<template lang="html">
  <div class="container" ref="container">
    <canvas ref="canvas" :width="width" :height="height"></canvas>
  </div>
</template>

<script>

export default {
  name: "monster",
  data ()
  {
    return {
      width: 512,
      height: 512
    }
  }
  methods: {
    resizeCanvas(){
      console.log(this.$refs.container.offsetWidth); // logs 0
      this.width = this.$refs.container.offsetWidth
      this.height = this.$refs.container.offsetWidth
    }
  },
  mounted ()
  {
    console.log(this.$refs.container.offsetWidth) // logs 0
    window.addEventListener("resize", this.resizeCanvas);
    this.resizeCanvas()  
  },
  unmounted() {
    window.removeEventListener("resize", this.resizeCanvas);
  },
}
</script>

<style lang="css" scoped>
.container {
  width: 100%; height: 100%
}
</style>

Answer №1

When using the mounted lifecycle hook in VueJS, it's important to note that the DOM may not be fully ready. To ensure that you can accurately check the dimensions of your container element, you will need to wait for this.$nextTick().

One approach is to move your logic into the callback of nextTick like this:

mounted () {
    this.$nextTick(() => {
        console.log(this.$refs.container.offsetWidth);
        window.addEventListener("resize", this.resizeCanvas);
        this.resizeCanvas();
    });
},

If you prefer using async/await, you can also achieve the same result with a cleaner syntax:

async mounted () {
    await this.$nextTick();

    console.log(this.$refs.container.offsetWidth);
    window.addEventListener("resize", this.resizeCanvas);
    this.resizeCanvas();
},

An alternative option is to delegate the responsibility of waiting for the DOM to be ready to the resizeCanvas function for better abstraction and separation of concerns:

methods: {
    async resizeCanvas(){
      await this.$nextTick();
      
      this.width = this.$refs.container.offsetWidth
      this.height = this.$refs.container.offsetWidth
    }
},
mounted () {
    window.addEventListener("resize", this.resizeCanvas);
    this.resizeCanvas();
},

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

Error encountered while attempting to retrieve an environment variable: Invalid token found

I am currently facing an issue while trying to add an environment variable inside the .env file in my Nuxt project. The version of Nuxt.js I am using is 2.15.3 Below is a snippet from my nuxt.config.js: export default { publicRuntimeConfig: { baseU ...

Update the input value following a successful action

How can I update the value of an input field after a successful ajax call? I have tried the following approach but it doesn't seem to be working. The result from the alert is 80000 Here is the HTML input code: <input class="form-control" type=" ...

Modify the color of the menu in OpenCart 1.5.6.4 to give it a fresh

In the default theme of OpenCart 1.5.6.4, I am looking to change the background color of the dropdown menu which is currently defined by the background image 'menu.png' to a custom hex value. The CSS code for this section is shown below: #menu & ...

Using this functionality on a ReactJS Functional Component

Hey everyone, I'm fairly new to using React and I'm currently trying to wrap my head around some concepts. After doing some research online, I stumbled upon a situation where I am unsure if I can achieve what I need. I have a functional componen ...

The height and alignment of the <a> tag and <p> element vary within a flex container

Currently, I am in the process of constructing a bottom navigation bar for a blog page. This navigation bar will allow users to easily navigate between the last blog entry, the main blog home/index, and the upcoming post. However, when the user reaches the ...

Having trouble getting my list items to display on individual lines within the foreach loop. It just doesn't seem to be working as expected

In the event listener, I need to ensure that my list items within the forEach loop are not displaying on separate lines. This issue is causing a problem in a lengthy section of code. The goal is to update questions when an answer is clicked from a list. B ...

Submitting an extremely large string to an Express server using JS

How can a large String be efficiently sent to a Node.js Express server? On my webpage, I am using Codemirror to load files from an Express server into the editor. However, what is the most effective method for sending "the file" (which is actually a bi ...

Is it possible for me to create a list in alphabetical order beginning with the letter B instead of A

My task involves creating a summary of locations using the Google Maps API. The map displays letters corresponding to different waypoints, and I have a separate <div> containing all the route information. Currently, I have the route information stru ...

At what point in time does the LoadingFrameComplete event in Awesomium typically happen?

According to the documentation from Awesomium, the event WebView.LoadingFrameComplete is triggered when a frame finishes loading. This description seems somewhat ambiguous. Does this event coincide with the JavaScript load event of the window? Or perhap ...

Ensure the footer remains fixed while scrolling

For the past day, I've been tackling a challenge with my online shop project. On the specific item's page, I want to include a fixed [add to cart] button as a footer initially, which then becomes sticky when scrolling to a certain point. You can ...

NG-model not visible to AngularJS Controller's filter

Finally, the code is working perfectly. It's a mystery to me. I created a custom filter to use with ng-repeat. The code is implemented within a Controller ... .controller('makeOrderController', function ($scope, $timeout, $ionicLoading) { ...

Is it possible to reference the same PHP file in multiple locations?

Currently, I am working on a web development project where I have created a header.html file to store the common header for all my webpages. This header file is located in the parent directory. Within my header.html file, I have included references to bot ...

Importing D3 data from CSV files using the "%" symbol

I am trying to import a CSV file with the following data: Month, Ratio January, 0.19% February, 0.19% March, 0.19% April, 0.18% The current code snippet I'm using is as follows: d3.csv("month_ct.csv", function(d) { return { month: d ...

The modal window pops up immediately upon the first click

Experience a dynamic modal element that springs to life with just the click of a button or an image. The magic lies in the combination of HTML, CSS, and jQuery code: <div id="modal-1" class="modal"> <div class="button modal-button" data-butto ...

Create and export a global function in your webpack configuration file (webpack.config.js) that can be accessed and utilized

Looking to dive into webpack for the first time. I am interested in exporting a global function, akin to how variables are exported using webpack.EnvironmentPlugin, in order to utilize it in typescript. Experimented with the code snippet below just to und ...

The FireBase dispatch functionality fails to update the real-time database

Struggling with a realtimeDB issue while using NuxtJS to manage state and send it to the DB. Saving data works fine, but editing results in a 400 BAD Request error. This error also occurs when trying to manually update information within Firebase realtime ...

Getting POST data in Next.js is a common task that requires understanding of how the

I am currently working on a form validation project using the App Router within Next.js. // app/register/page.tsx export default function Register(context: any) { console.log("Register page", context.params, context.searchParams); return ...

Customizing a ControlsFX PopOver in a JavaFX application

I am looking to personalize the appearance of a JavaFX PopOver control. I have a button that triggers the display of the PopOver. Below is a functional example: package custompopover; import javafx.application.Application; import javafx.event.ActionEvent ...

What is the best way to automatically remove a Firebase database entry when a user has been inactive for a period of time, without logging out but simply not accessing the page for an extended duration?

Currently, when a user clicks 'logout', their session is terminated, and a database entry is removed. All other users can see that database entry, so the objective is for users to view each other's data only while they are logged in. For in ...

What is the best way to display a scrollbar at the bottom of the table while setting the table height to

After writing the css provided below, I noticed that it works fine on my laptop screen. However, when viewing it on a larger monitor, there is empty space at the end of the table. .wrapper{ width:auto; height: 500px; overflow-x: scroll; ...