Tips for automatically resizing a canvas to fit the content within a scrollable container?

I have integrated PDF JS into my Vue3 project to overlay a

<canvas id="draw_canvas">
on the rendered pdf document. This allows me to draw rectangles programmatically over the pdf, serving as markers for specific areas.

The rendering process of a pdf file using PDF JS involves placing each page's content inside separate <canvas> elements. In my project, I have two Vue Single File Components (SFCs) named App and Child. The Child component loads and displays the pdf's pages (3 in total) within a scrollable container

<div id="pages_container">
, which is nested inside another
<div id="doc_container">
.

To dynamically adjust the height of

<canvas id="draw_canvas">
as the
<div id="pages_container">
expands, I utilize a ResizeObserver that monitors changes in the size of the
<div id="pages_container">
and updates the canvas' height to match its offsetHeight.

Answer №1

When working with the HTML <canvas> element, it's important to understand that it has both intrinsic dimensions (determined by the .width and .height properties in JavaScript) and displayed dimensions (controlled by CSS width and height properties).

In your scenario, adjusting the canvas height using

drawCanvas.height = offsetHeight;
affects the intrinsic dimensions, which then get scaled because of the CSS width being set as 100%.

To resolve this issue, consider setting the style.height property to the offset height and specify that these are pixel measurements for the style properties.

drawCanvas.style.height = `${offsetHeight}px`;

If you notice discrepancies even after making these adjustments, keep in mind that the offsetHeight value includes inner height, padding, and borders. Therefore, ensure you account for padding and borders when setting the canvas size.

Refer to the W3C spec on canvas dimensions for more information

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

Is it wise to question the validity of req.body in express.js?

https://expressjs.com/en/4x/api.html mentions It is crucial to validate all properties and values in the req.body object as they are derived from user input. Any operation performed on this object should be validated to prevent security risks. For instan ...

Is it possible to obtain the parameters using an empty object with the getStaticPaths function?

Within the getStaticPaths function, a path is returned with params postId:1. If additional params like postId: 2 or postId: 3 are included, they will also be statically generated. Is my understanding correct? Is there a way to avoid loading any post based ...

Redirecting to another page with a simple link is not recommended

Once the user successfully logs in, I redirect them to the dashboard. Everything was working fine until I deployed it using tomcat. Now the URL is http://localhost:8080/myWar/ So when I use this: window.location.href = "/dashboard"; it redirects to ht ...

knockout, loop within a loop

Imagine I have a group of Humans who own Cats, and those Cats have Kittens class Person { String name; Cat[] cats; } class Cat { String name; Kitten[] kittens; } class Kitten { String name; } Now I want to display all my Kittens with ...

Import existing data from a pre-filled form - VueJS - Bootstrap-Vue

I'm facing an issue with a form that has linked selects. When one select is filled, the other select should also be filled with the corresponding code. However, when opening the modal with the field value, it fails to load the value. I suspect this mi ...

Create a JavaScript variable that is initialized with a value from an AngularJS scope

What is the best way to assign a value from an AngularJS scope variable to a JavaScript variable? For example: xyz.controller({ $scope.country = "Canada"; }); Here's how you can do it in JavaScript: <script> var country = {{scope.countr ...

When my contact form is viewed on mobile, an unexpected margin appears

On my main page, I have a contact form positioned on top of an image slider that appears like this: https://i.sstatic.net/aGnj1.png The contact form is nested inside the slider's div as shown below: <div class="img-slide"> <div c ...

The AngularJS 2 application reports that the this.router object has not been defined

My function to sign up a user and redirect them to the main page is implemented like this: onSubmit(){ this.userService.createUser(this.user).subscribe(function (response) { alert('Registration successful'); localStor ...

Is there a way to launch my JavaScript project locally and have index.html served on an npm server?

I am currently attempting to launch a specific Single Page Application (SPA) project using pure JavaScript. This project consists of a script file and an index.html file. I am trying to run this project on my local machine, but it requires that it be hos ...

Adjust the size of the wrapper/mask as the browser is resized

Is there a way to adjust the size of my wrapper and mask when the browser is resized? Currently, the mask stops once it's loaded, causing the content to be cut off when scrolling. You can view an example on this site. $(document).ready(function() { ...

Issue with the first-child selector

Is this supposed to work or am I losing my mind? .project.work:first-child:before { content: 'Projects'; } .project.research:first-child:before { content: 'Research'; } <div class="project work"> <p>abcdef</p> ...

I'm encountering some strange blank white space when I view my webpage on a phone or Safari. It seems to be affecting the CSS grid and flexbox of images

Currently, I am engaged in a 180-day challenge to create webpages on . For website number 9, the task at hand is to showcase 8 images in a grid layout. Surprisingly, this layout appears flawlessly on my Mac when using Chrome but encounters issues displayin ...

Having trouble with Vue component not showing updated data after axios POST request issue

Hi there, I'm facing an issue and could really use some guidance from a skilled Javascript Wizard. Here's the problem: I have a Laravel collection that I'm passing to a Vue component. Within the component, I am looping through the collecti ...

Vue Error: "the main template must have one and only one root element"

Exploring My Component Setup components exposed: <template> <!--<post-form/>--> <div class="wrapper"> <b-table :data="posts"> <template slot-scope="props"> <b-table-column fie ...

Switch body class when the navbar's collapse show class is toggled

There are numerous methods to accomplish this task, but I am seeking the most optimal and efficient approach. My goal is to toggle a custom body class when the .navbar-toggle triggers the .show class on the .navbar-collapse element. I'm hesitant abo ...

How to highlight all the text within a 'pre code block' when double-clicked using JavaScript

Is there a way to make code blocks on my blog automatically selected when double-clicked without using jQuery? Here is the code I have so far: I apologize if this is a silly question, I am still learning! <script type="text/javascript" src="https://c ...

Changing the state of an object property within a Vue watch

In my current project, I am attempting to set the selected boolean value to true in an array of objects based on certain conditions. Specifically, I want to update the selected property in the items array when the from_id matches the item_id in another arr ...

The issue of font icons not displaying seems to be affecting all users

I have developed my own website that functions similar to fontawesome. However, after uploading it to an online server, I encountered a problem where others are unable to use my custom font icon. In order for someone to utilize the font icon from my websi ...

Sending data in chunks using Vue.js

I'm interested in sending the data in chunks. Currently, what I send to the server looks like this: for loop - 1, 2, 3. However, the server receives it asynchronously as 3, 1, 2 and I need it to be received synchronously in the order of my for loop: 1 ...

Dynamic loading of lists necessitates encapsulating nested lists

I'm currently working on a 3-level dropdown list that pulls content from a database for my project. I want the top level to resemble a tab menu, with a border surrounding the area underneath where the additional lists will appear. However, I am facing ...