Adjusting the dimensions of a shape proportionally as the window size is altered through the onWindowResize() function

After completing some coding courses, I am now venturing into the world of WebGL using Three.js to enhance my programming skills.

I have been experimenting with a widely used function in examples on threes.org:

        function onWindowResize() {

          camera.aspect = window.innerWidth / window.innerHeight;
          camera.updateProjectionMatrix();

          renderer.setSize(window.innerWidth, window.innerHeight);

        }

This function allows me to adjust the size and centering of my geometry based on the width and height of my browser window. However, I have encountered an issue when decreasing the width of the window where my geometry becomes cut off due to its centralized positioning without scaling down proportionally.

In an attempt to rectify this problem, I implemented object.scale.devideScalar(1.5); within my onWindowResize() function in this example: http://codepen.io/gnazoa/pen/BjoBZz. Unfortunately, this adjustment did not solve the issue.

The discrepancy between how the geometry appears on my desktop screen compared to on my iPhone illustrated the importance of finding a solution for this problem:

https://i.sstatic.net/AerXK.png

https://i.sstatic.net/nSrqN.png

If you have any suggestions or insight on resolving this dilemma, it would be greatly appreciated as I strive for an optimal user experience regardless of device.

Answer №1

Welcome to the wonderful world of js/Three.js! Thank you for sharing your fiddle with us. If you're interested, here's my recommended solution.

1) Just a heads up, there's a small typo on line 44

object.scale.devideScalar(1.5);

should be

object.scale.divideScalar(1.5);

If you check your browser's dev tools (chrome, firefox, or any other browser), you might see an error message like:

Uncaught TypeError: object.scale.devideScalar is not a function

2) Even after fixing that issue, there's another problem. The way you've written the code alters the scale of the three.js cube by reducing it by 66% every time onWindowResize() is called. Consequently, the cube disappears quickly as its scale diminishes. Not ideal.

To ensure that the object's scale retains the same proportions relative to the screen size during resize, regardless of the initial or resized dimensions, you need a different approach.

The renderer cannot be stretched without distorting the 3D projection, nor can a cube fill any screen without distortion. As such, my radical suggestion is not to resize the canvas to completely fit the container. Instead, create a containing div that partially fills the window and adjust the css accordingly.

I have included some new code in my proposed solution. This code snippet focuses on maintaining aspect ratio when resizing the preview window:

var targetAspectRatio = 16 / 9; //cinematic!
function aspectSize(availableWidth, availableHeight) {
  var currentRatio = availableWidth / availableHeight;
  if (currentRatio > targetAspectRatio) {
    return {
      width: availableHeight * targetAspectRatio,
      height: availableHeight
    };
  } else {
    return {
      width: availableWidth,
      height: availableWidth / targetAspectRatio
    };
  }
}

This method ensures that the rectangular content retains its aspect ratio when adjusting to different screen sizes.

Feel free to customize the code further to suit your needs. Good luck with your project!

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

What could be causing my Google Chrome extension to only allow me to open 25 tabs instead of more?

Having a frustrating issue with my code that is causing problems when used as a Chrome Extension. Despite checking and confirming that the code should work correctly, it seems to stop opening pages after tab 25. I have verified that the code attempts to o ...

What is the best way to differentiate between a JSON object and a Waterline model instance?

Note: I have posted an issue regarding this on the Waterline repo, but unfortunately, I have not received a simpler solution than my current workaround. Within my User model, along with default attributes such as createdDate and modifiedDate, I also have ...

Error: The URL type "workspace:" is not supported: workspace:*

I am embarking on a new project using Gatsby. You can create your project by running the following command: gatsby new YourProjectName2 https://github.com/Vagr9K/gatsby-advanced-starter However, I encountered an error message: info Creating new site fro ...

A singular Vuejs Pinia store utilizing namespaced actions

Is it possible to separate pinia actions into two distinct namespaces, allowing access through properties n1 and n2 like this: // current store.n1a('hi') store.n2b() // wanted store.n1.a('hi') store.n2.b() // cumbersome workaround: sto ...

What is the best way to transform an array of objects in JavaScript?

I'm working with an array of objects that I need to transform into a table by pivoting the data. In other words, I am looking to generate a new array of objects with unique titles and nested arrays of key-value pairs. Can someone please assist me in a ...

Unexpected activity in Socket.io

Attempting to develop a chat roulette app involves initiating a socket connection when the user clicks the ACCEPT button. In order to connect only two users at a time, a randomId is generated on the frontend along with the sessionId sent in the cookie head ...

The promise is only guaranteed to resolve correctly upon the refreshing of the page

Exploring an API that retrieves a list of Pokemon and related data, the code snippet below demonstrates how to achieve this. export function SomePage() { const [arr, setArray] = useState([]); useEffect(() => { fetchSomePokemon(); }, []); f ...

Is it possible for me to determine the quantity of lines present in the text without any

I have a user-input field where individuals can enter information. The input can range from no information at all to as little as a single word or unlimited characters. However, my focus is on handling cases where the text exceeds three lines. To address ...

Tips for invoking a function from a JavaScript file within an Angular component

This particular query remains unanswered and pertains to AngularJS. I am seeking a solution specifically for Angular, as none of the existing answers online seem to be effective in my case. Here is an outline of my code: Columns.js export class Columns { ...

I encountered a permission denied error when trying to enter DEBUG=app ./bin/www in Node.js

After renaming 'my-application' to just 'app', I encountered an issue when running the DEBUG command in the terminal: I used DEBUG=app ./bin/www Originally, it was named 'my-application' as created by express. However, after ...

Unable to invoke parent method from child component in Vue causing issue

I am facing an issue where I am trying to trigger a method in the parent component from the child component using $emit, but for some reason, it is not working as expected. Can someone please help me troubleshoot this problem? Parent Component <templat ...

How can I use jQuery to separate special characters from letters in a string?

I'm facing an issue with my code related to validation. There is a existing validation in place that restricts users from entering letters and special characters in a textfield. Now, I need to incorporate this validation into my code but I'm uns ...

Adding up values of objects in a different array using Vue.js

Recently, I started using VueJs and encountered an object that contains arrays. One of the tasks I need to accomplish is to display the total sum of all amounts in one of the columns of the table. Here is my table structure: < ...

Is there a way to verify that a form field has been completed?

Currently, I am grappling with a method to clear a field if a specific field is filled in and vice versa. This form identifies urgent care locations based on the information provided by users. The required entries include the name of the urgent care facil ...

Can you explain the functions of this "malicious" JavaScript code?

I came across this piece of code on a website that labeled it as "malicious" javascript. Given my limited knowledge of javascript and the potential risks involved in trying out the code on my own site, I was hoping someone here might be able to shed some l ...

When the page initially loads, the block appears on top of the upper block and remains in place after the page is refreshed

Upon initial loading, the block appears on top of another block but remains fixed upon page refresh. The same issue occurs in the mobile version of the site and occasionally displays correctly. The website is built on WordPress and optimized using Page Spe ...

Maintaining microsecond accuracy when transferring datetime values between Django and JavaScript

It appears that django, or the sqlite database, is saving datetimes with microsecond precision. However, when it comes to transferring a time to javascript, the Date object only works with milliseconds: var stringFromDjango = "2015-08-01 01:24:58.520124+1 ...

What is the proper way to integrate "require" into my Angular 2 project?

Currently, I am still in the process of trying to integrate the angular 2 code mirror module into my angular 2 application. Previously, I faced some challenges with imports which I discussed in detail here, and managed to overcome them. However, a new iss ...

Utilizing the doGet approach to send form data upon clicking a button

I am attempting to incorporate a button of type="button" on a form that will process the information using the doGet method instead of doPost for the purpose of updating the URL correctly. Due to this requirement, I am unable to utilize type="submit" or do ...

Using jQuery to retrieve the TD value

I'm attempting to retrieve the TD value using the Value attribute.... Let's say I have the following HTML markup: <td nowrap="nowrap" value="FO2180TL" class="colPadding" id="salesOrderNumber1">bla bla </td> So, I tried this- v ...