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

The Vue instance seems to be unable to recognize the shims-vue.d.ts file

I encountered an issue with my Vue file. Here is the code snippet: import Vue from 'vue'; import VueRouter from 'vue-router'; export default Vue.extend({ name: 'MyComponentsName', methods: { doRedirect() { this. ...

Having trouble posting data in node.js using MongoDB and EJS

Hey everyone, I'm currently working on creating a page with a form and text input fields. However, I'm encountering an error that says "Cannot Post". Here is my code, any help would be greatly appreciated. Why isn't it working? This is app. ...

Tips on personalizing the FirebaseUI- Web theme

Can someone help me find a way to customize the logo and colors in this code snippet? I've only come across solutions for Android so far. if (process.browser) { const firebaseui = require('firebaseui') console.log(firebaseui) ...

Struggling with Bootstrap 4 - need help with navbar and flexbox alignment issues

My goal is to recreate a navigation bar similar to this design: navbar I initially attempted to use the grid system for my navbar, but it didn't work out as expected. After some research, I found that using the grid system for navbars is not recomme ...

Assign a value to the initial column of a row if the ID is found in the array

I'm attempting to set checkboxes within a specific range. The firebase_id array needs to correspond with column B in that range. If they match, the row should be set to TRUE. However, I am encountering issues where some checkboxes are randomly checked ...

JavaScript's replace() method and the $1 issue

My goal is to develop a script that can identify specific patterns within text and then enclose them in particular tags upon identification. $(".shop_attributes td").each(function () { $(this).html(function(i, html) { return html.replace(/E[0- ...

Explore the world of HTML event listening through .NET integration

Imagine this scenario: within an HTML page, using an UpdatePanel, you have a loading animated gif spinning while ASP.NET processes data from a webservice. I'm curious if there's a way to create an Event in .NET code that can be detected on the H ...

CSS: Adjusting the position of tooltips to align with the triggering element (rest of code is fully functional)

Looking to create a custom tooltip without relying on plugins. The goal is to align the tooltip vertically to the right of the triggering element, in this case, an input field. The current setup (see Fiddle demo) achieves the desired layout and content fo ...

JavaScript - Utilizing an image file in relation to a URL pathway

Is there a way to reference an image URL using a relative path in a JavaScript file similar to CSS files? To test this, I created two divs and displayed a gif in the background using CSS in one and using JavaScript in the other: -My file directory struct ...

Solving complex promises in both serial and parallel fashion

My current function performs four tasks that must be executed in a specific sequence: - promise1 - promiseAfter1 // In parallel - promise2 - promiseAfter2 To ensure the promises are handled sequentially, I have structured two separate functions as follows ...

Is there a way to incorporate a text box in javascript that displays the retrieved reference count from the database?

I'm currently working on creating a functionality that retrieves rows with the same ID from a database and displays them in a text box. Below is the PHP code I've written for retrieving all the rows: PHP: <?php include_once('pConfig ...

The res.download() function in Express is failing to deliver the accurate URL to the client

When trying to utilize the res.download() method for downloading specific files from a server, there is an issue where triggering the res.download does not redirect the client to the correct URL. The files intended for download are located in a directory s ...

The combination of Next.JS and React Objects is not acceptable as a React child

Summary: Encountering the error Error: Objects are not valid as a React child (found: [object Promise]) while making a fetch request in a Typescript project. Interestingly, the same code snippet works without errors in a Javascript project. Recently, I ...

In vue, pagination links are displayed as dots instead of numbers

Struggling to integrate pagination in vue. Facing an issue where the pagination links are appearing as dots, depicted in the attached image. The correct number of pagination links display and I can navigate through different pages using the side navigation ...

Disable hover effects in CSS with JavaScript

I am looking for a way to deactivate CSS hover functionality using JavaScript. Within a form, there is a button that sends data to the database server. By utilizing OnClientClick() of an ASP.NET Button control, my goal is to modify the text of the element ...

Spinner displayed upon task completion

Currently, I am developing a project using Spring Boot. I would like to display a spinner on my page to indicate that a task involving heavy calculations is in progress. Even though the page may take up to 5 minutes to load, my spinner only appears for t ...

Exploring the intersection of Nuxt and TypeScript with the powerful `defineProps`

I am currently utilizing the Nuxt 3 / Vue 3 defineProps in conjunction with TypeScript and I am looking to automatically deduce prop types from TypeScript types. import { User } from '~/types/types' const props = defineProps({ users: { typ ...

Determine the index of a specific character within a string using a "for of" loop

How can I obtain the position of a character in a string when it has been separated programmatically using a for...of loop? For instance, if I wish to display the position of each character in a string with the following loop: for (let c of myString) { ...

How can I showcase the selected file using jQuery's querySelector?

I have successfully implemented a file upload feature using jQuery querySelector. Now, I am looking for a way to display the selected file name in a span element after the user selects the file. Here is my HTML code: <span id="filename"></span&g ...

Break down objects into arrays of objects in JavaScript

Hello, I'm struggling with transforming this object into an array of objects. The 'number' and 'reason' fields are currently stored as strings separated by commas. I need to split them into their own separate objects. The example ...