Creating dynamic height based on width using JavaScript

I'm trying to make a rectangle responsive based on the width of the window.

This is my current logic:

aspectRatio = 16 / 9
win = {
    width: window.innerWidth,
    height: window.innerHeight,
}

get browser() {
    const width = this.win.width - 250
    const height = width / this.aspectRatio

    return {
        width,
        height,
    }
}

To calculate the width, I subtract the sidebar width (250) from win.width.

For the height, I divide the width by the aspectRatio.

However, when the window size is reduced to around 700px, it results in a height of 0.

My application can be seen here:

https://i.stack.imgur.com/rqpVc.png

Demo →

CodeSandBox → https://codesandbox.io/s/add-padding-to-centered-canvas-with-sidebar-gqhhl

I want the papayawhip rectangle to be responsive. What algorithm should I use? I'm using Canvas with KonvaJS but the logic is written in JavaScript.

How can I make it responsive and maintain proportionality as the height shortens quickly?

Answer №1

Below is the approach I took:

function App() {
  const storage = useStorage();
  const { victory, navigator, aspect } = storage;
  const offset = 50;

  const widthOfRect = navigator.width - offset;
  const heightOfRect = widthOfRect / aspect;

  return (
    <div className="flex">
      <div id="sidebar">
        <h1 className="text">
          Center <span>papayawhip</span> Canvas
        </h1>
      </div>
      <Stage width={navigator.width} height={navigator.height} id="konva">
        <Layer>
          <Rect
            width={widthOfRect}
            height={heightOfRect}
            x={offset / 2}
            y={(victory.height - heightOfRect) / 2}
            fill="papayawhip"
          />
        </Layer>
      </Stage>
    </div>
  );
}

Additionally, I updated the storage setup so that navigator gives back the canvas area:

get navigator() {
        const width = this.victory.width - 250
        const height = this.victory.height

        return {
            width,
            height,
        }
}

Demo: https://codesandbox.io/s/react-konva-responsive-canvas-ogk1n

Answer №2

Initial Answer

width: 100%;
padding-top: 56.25%; /* Maintaining a 16:9 Aspect Ratio */

Alternative Approach

padding-top: calc(9 / 16 * 100%);

Answer №3

If you find yourself in a situation where you need to make CSS changes, but your component is buried 3 levels deep, don't worry! You can easily access the CSS file that is already imported next to your .tsx file.

To achieve this, simply add the following line of code at the end of your file:

import "./styles.css"

This trick, borrowed from @deadcoder's solution for resolving ratio issues, will ensure that your component displays correctly across different screen sizes. Take note of the responsive breakpoints provided below to maintain the aspect ratio and prevent shrinking to nothing.

canvas {
  width: 100%;
  padding-top: 56.25%; /* 16:9 Aspect Ratio */
}

@media screen and (max-width: 1200px) {
    canvas {
      width: 100%;
      height: 400px;
      padding: 0; /* reset the ratio for smaller sizes so you can crop it */
    }
}
@media screen and (max-width: 600px) {
    canvas {
      width: 100%;
      height: 200px;
      padding: 0; /* reset the ratio for smaller sizes so you can crop it */
    }
}

Additionally, consider assigning an ID or class to the canvas element for easier targeting.

If you are still experiencing issues with the height disappearing too quickly, try using the entire area as the canvas or utilizing a background image instead.

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

How to delete the final character from a file stream using node.js and the fs module

My current project involves using node.js to create an array of objects and save them to a file, utilizing the fs library. Initially, I set up the write stream with var file = fs.createWriteStream('arrayOfObjects.json'); and wrote an opening brac ...

Having trouble getting CSS styles to work properly in conjunction with Javascript code

Currently, I am developing a feature on a canvas that covers the entire webpage's width and length. In this canvas, I have the ability to create boxes by clicking down anywhere on the canvas, dragging my mouse in any direction, and upon releasing the ...

Utilize formData to upload an image to a database with ajax

I'm struggling with the process of uploading an image from an HTML form. The goal is for the form to send the image name along with other data to a PHP page. Instead of using the serialized function, I opted for formData as it has the capability to h ...

The parseFloat function only considers numbers before the decimal point and disregards

I need my function to properly format a number or string into a decimal number with X amount of digits after the decimal point. The issue I'm facing is that when I pass 3.0004 to my function, it returns 3. After reviewing the documentation, I realized ...

Updating choices within a div in real-time by changing the select box dynamically

I need to swap out the select box that is nested inside this div <div class="models"> <select disabled="disable"> <option>Model Name</option> </select> </div> I am attempting to target the div and manipul ...

The equivalent of the $.curCSS method in jQuery version 1.10 is as follows:

While working with a library called mcdropdown from http://www.givainc.com/labs/, I encountered an issue with the $.curCSS method. The latest version of jQuery no longer supports this method and suggests using $().css instead. Following the documentation, ...

The implementation of local JSON instead of external JSONP in Angular

I am exploring the option of storing a json-file on the same server as my Angular app. I am wondering about how I can modify this code to read from a locally stored json file: ergastAPI.getDrivers = function() { return $http({ method: 'GET&apos ...

How come useEffect runs only once even when multiple states in the dependency array of useEffect change simultaneously?

<div onClick={() => { updateValue1((x: number) => x + 1); updateValue2((x: number) => x + 3); }} > one? two? </div> const [value1, updateValue1] = useState(1); const [value2, updateValue2] = useState(1 ...

Is there a way to invoke a function in an iframe from its parent?

How can I call a function that is in an iframe from the parent document? If the function were in the parent, I could simply use parent.func(); but since it's within the iframe, how can I still call it successfully? JavaScript keeps saying it can' ...

What is the best way to retrieve the "name" and "ObjectId" properties from this array of objects? (Using Mongoose and MongoDB)

When trying to access the name property, I encountered an issue where it returned undefined: Category.find() .select("-_id") .select("-__v") .then((categories) => { let creator = req.userId; console.log(categories.name) //unde ...

What is causing the ESLint error when trying to use an async function that returns a Promise?

In my Next.js application, I have defined an async function with Promise return and used it as an event handler for an HTML anchor element. However, when I try to run my code, ESLint throws the following error: "Promise-returning function provided t ...

Integrating Material-UI Dialog with Material-table in ReactJS: A Step-by-Step Guide

I have implemented the use of actions in my rows using Material-Table, but I am seeking a way for the action to open a dialog when clicked (Material-UI Dialogs). Is there a way to accomplish this within Material-Table? It seems like Material-UI just appen ...

Changed over to a promise-oriented database, causing my login feature to malfunction completely

Although I can successfully register, when I am redirected to my game route, all I see is a blank Error page with [object Object] on the screen. This message also appears in my console periodically. Initially, I suspected an issue related to socket.io, bu ...

What causes Chrome to crash when dealing with lengthy tail files?

My objective is to display a log file in real-time using a websocket connection. However, I am facing performance issues with Chrome when the paragraph ('p') element in the HTML becomes large (about 450 lines). This is the current implementation ...

Adding miscellaneous PHP scripts

When a user clicks on the sample button, my PHP code gets appended. It works fine, but I want to clean up my process. After some research, I learned that using jQuery AJAX is the way to go. The only problem is, I'm not sure how to implement AJAX. I&ap ...

What could be causing the resolve method to not send any data back to the controller?

While following a tutorial on YouTube, I encountered an issue with incorporating the resolve method getposts into the contactController. Despite my efforts, no value is being returned. I've spent hours searching for answers on Stack Overflow to no av ...

Is it possible to incorporate varied icon images for every item in an unordered list?

While I'm not an CSS expert, I do have a decent understanding of it. My current project involves creating an unordered list with unique icons for each item, along with changing the background color upon hover. I wonder if there's a way to achiev ...

Examining the version of a node module installed in the local environment and comparing it

One of the reasons I am asking this question is because I have encountered challenges while collaborating with other developers. At times, when other developers update node module versions, I forget to install these new modules after pulling the latest co ...

Tips for utilizing dynamic variables when setting props in React Native styles

I am encountering an issue while trying to set props in the stylesheet to dynamically change the background color based on data received from the server. undefined is not an object (evaluating 'this.props.colorCode') Below is the snippet of my ...

What is the process for fetching a specific image from a database folder by referencing its name?

We have a collection of images stored in the uploads folder within the root directory. Our goal is to display a single image for each user profile. Each user's profile image file name is saved in the database table called user under the field profile ...