Adjusting canvas/webgl dimensions to match screen width and height

Hey, I'm currently working on resizing my canvas/webgl to fit the window's height and width at 100%. It works initially, but when I resize the window from small to large, it doesn't scale/fit properly anymore and remains small. Any suggestions on how to fix this issue? JSfiddle: http://jsfiddle.net/jyr6y3fx/

Here's the code:


var scene, renderer;
var glitchPass;

init();
animate();

function init() {
    renderer = new THREE.WebGLRenderer({ alpha: true });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.z = 400;

    scene = new THREE.Scene();

    composer = new THREE.EffectComposer(renderer);
    composer.addPass(new THREE.RenderPass(scene, camera));

    glitchPass = new THREE.GlitchPass();
    glitchPass.renderToScreen = true;
    composer.addPass(glitchPass);
}

function animate() {
    requestAnimationFrame(animate);
    composer.render();
}

Thank you for any help!

Answer №1

It's quite disheartening to see the other solutions, as they seem to be in constant conflict with the browser instead of working alongside it.

The most effective approach for resizing three.js is to code it in a way that simply adapts to the size set by CSS on the canvas element. This ensures that your code remains functional regardless of how you use the canvas, eliminating the need for adjustments in different scenarios.

Initially setting the aspect ratio serves no purpose since we will be updating it based on the canvas size changes, making it redundant to set it multiple times in the code:

// There's no reason to set the aspect here because we're going
// to set on resize anyway
const camera = new THREE.PerspectiveCamera(70, 1, 1, 1000);

We then incorporate code that resizes the canvas to match its display dimensions:

function resizeCanvasToDisplaySize(force) {
  const canvas = renderer.domElement;
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;

  if (force || canvas.width !== width || canvas.height !== height) {
    // Ensure smooth coordination with the browser by passing false
    renderer.setSize(width, height, false);
    camera.aspect = width / height;
    camera.updateProjectionMatrix();

    // Update any render target sizes here
  }
}

Include this function in your rendering loop and call it once during initialization:

function animate(time) {
  time *= 0.001; 

  resizeCanvasToDisplaySize();

  mesh.rotation.x = time * 0.5;
  mesh.rotation.y = time * 1;

  renderer.render(scene, camera);
  requestAnimationFrame(animate);
}

resizeCanvasToDisplaySize(true);
requestAnimationFrame(animate);

For achieving fullscreen display, the following CSS rules are all that's required:

body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }

Four examples showcasing different scenarios are provided below. The only varying factor among them is the CSS styling and the method of creating the canvas, while keeping the code unchanged:

Example 1: Fullscreen display where we create the canvas

[Code snippet for Example 1]

Example 2: Fullscreen canvas created by three.js

[Code snippet for Example 2]

Example 3: Inline canvas

[Code snippet for Example 3]

Example 4: Canvas at 50% width (like a live editor)

[Code snippet for Example 4]

The implementation above functions seamlessly without referencing window.innerWidth or window.innerHeight, demonstrating its versatility across various scenarios.

Why avoid using the resize event? There are instances where no resize event is triggered even though the canvas size changes, such as when implementing a 2-column editor with a movable divider between columns or scaling the canvas based on nearby content. In such cases, relying solely on the resize event may not suffice.

Answer №2

The reason for this issue is that the width and height of the renderer are fixed and do not adjust when the browser window is resized.

To fix this problem, you can reset the width and height of the renderer on window resize by adding the following code snippet:

window.addEventListener('resize', function() {
   renderer.setSize(window.innerWidth, window.innerHeight);
});

For a demonstration, check out this working JSFiddle

Answer №3

Creating a responsive canvas that adapts to fullpage

When it comes to resizing based on window changes, the most efficient way is to handle it within the animation loop rather than relying solely on the window resize event. This approach ensures smoother resizing, especially when the window is being resized using a mouse.

To achieve this, you can position the canvas absolutely using CSS:

canvas { position : absolute; top : 0px; left : 0px; }

Here's some code snippet:

function animate(){
    if(renderer.domElement.width !== innerWidth || renderer.domElement.height !== innerHeight) {
        // Prevent Three from setting canvas.style width and height properties
        renderer.setSize(innerWidth,innerHeight,false); 
        camera.aspect = innerWidth / innerHeight;
        camera.updateProjectionMatrix();

    }

    // Render your scene here

    // Call for the next frame
    requestAnimationFrame(animate);
}

Answer №4

Dealing with resizing issues can be a real headache, especially when it comes to changes in device orientation. I tried all the standard solutions, which are usually found in places like https://jsfiddle.net/Q4Jpu/

However, what ultimately resolved the problem for me was getting rid of the initial

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

before adding the canvas element with

container.appendChild(renderer.domElement)
. Having that initial size set caused the canvas element to be stuck with fixed dimensions that didn't update on resize.

Now, I make sure to call the onWindowResize() function after completing all other initialization tasks, in addition to having it listen for the resize event.

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

Enhancing HTML through Angular 7 with HTTP responses

Sorry to bother you with this question, but I could really use some help. I'm facing an issue with updating the innerHTML or text of a specific HTML div based on data from an observable. When I try to access the element's content using .innerHTM ...

Create a series of vertical lines using jQuery

I'm dealing with a JSON data set that I want to use to generate a grid. In addition to the grid, I also need to display vertical lines above it based on certain values: var arr = []; arr= [ {"Measure":"Air Pollution","Rank":"1","Value":"15.5"}, ...

In Angular, you can easily modify and refresh an array item that is sourced from a JSON file by following these steps

Currently, I am working on implementing an edit functionality that will update the object by adding new data and deleting the old data upon updating. Specifically, I am focusing on editing and updating only the comments$. Although I am able to retrieve th ...

Adjusting the array when items in the multi-select dropdown are changed (selected or unselected)

I am looking to create a multi-select dropdown in Angular where the selected values are displayed as chip tags. Users should be able to unselect a value by clicking on the 'X' sign next to the chip tag, removing it from the selection. <searcha ...

Tips for extracting the two characters following a space in a string with or without the use of regex

How can I extract only the initials of 2 characters after spaces? See the code snippet below: const name = "John Peter Don"; const result = name.match(/\b(\w)/g).join(''); console.log(result)// JPD->> i want only JP ...

Ways to adjust text color after clicking on an element

Just a heads up, I didn't write all of the web-page code so I'm not exactly sure what pdiv is. But I want to see if I can fix this small issue [making text color change when clicked on to show which section you're reading]. This particular ...

The attempt to register a ServiceWorker for the angular scope was unsuccessful

I have encountered various solutions to this issue, some of which are not suitable for Angular and others simply do not work. In my quest to implement the "add to Homescreen" feature, I came across a helpful blog post (https://blog.betapage.co/how-to-add ...

A guide on efficiently traversing a disk directory, recursively fetching all paths in relative format, and converting them into a JSON stream with node.js

My goal is to traverse a directory tree and store it in a JSON file using node.js with the following approach: Open specified directory Convert paths into a relative format. For example: Directory: C:/test { {"C:/test folder 1": [ {"folder 1": ["fil ...

The Sortable feature is functional in all browsers except for Firefox

I am currently utilizing the following example () within my asp.net application. I have successfully implemented the sortable feature in all browsers except for Firefox, where it seems to trigger the event but doesn't execute the code. $('.c ...

ReactJS: Want to update card design by utilizing the onClick event handler

Currently, I am aware that there will be a need to refactor this code later on to separate things into their own components. However, due to time constraints, I have to wire this up as is at the moment. To achieve this, I utilized array.map() to create car ...

Guide to automatically loading a default child route in Angular 1.5 using ui-router

Hello, I am looking to set a default child route to load as soon as the page loads. Below is the code snippet: $stateProvider.state('userlist', { url: '/users', component: 'users', data:{"name":"abhi"}, resolv ...

Continuous Scrolling with Callback Function in jQuery

I have implemented the infinite-scroll plugin, which replaces traditional pagination with ajax to fetch new pages. The issue I am facing is that jQuery functions do not recognize the new posts, causing certain functions like the ones below to stop working ...

Building an integrated Monaco editor using Electron and AngularJS

Struggling to integrate the Monaco editor into my Electron app. Despite following electron examples, encountering persistent errors in my application. The errors I'm facing include: "loader.js:1817 Uncaught Error: Unrecognized require call" "angula ...

Error encountered in Selenium WebDriver due to JavascriptException

Attempting to execute JavaScript within Selenium WebDriver has resulted in an error. The script was stored in a string variable and passed to the `executeScript()` method. Upon running the script, a `JavascriptException` occurred. Below is the code snippet ...

Tips for validating updates in MongooseEnsuring data integrity is

My current Schema does not validate upon updating. Can you please point out where I went wrong and help me fix it? ...

Struggling to incorporate a Search Filter feature into my React project, unfortunately, it doesn't seem to be functioning correctly. Any assistance would be greatly appreciated. Can anyone lend

Hey there! I'm diving into the world of React and currently working on creating a search filter that fetches data from an API. Despite not encountering any errors in the console, it seems like my search bar isn't functioning properly. Any suggest ...

What are some best practices for preventing unforeseen rendering issues when utilizing React Context?

I am encountering an issue with my functional components under the provider. In the scenario where I increase counter1 in SubApp1, SubApp2 also re-renders unnecessarily. Similarly, when I increase counter2 in SubApp2, SubApp1 also gets rendered even thou ...

Experiencing trouble with calculating the total value of an array of objects due to NaN errors

I've been working on developing this web application in VUE.js, but I'm facing an issue with a specific function where I am attempting to sum the values of each object within an array. This is resulting in a NaN (Not a Number) error. Let's t ...

When is the best time to access user credentials in the FirebaseUI authentication process?

Referring to a provided example on using firebase authentication with Next.js from the Next.js github, I have noticed that many projects I have studied incorporate createUserWithEmailAndPassword at some point. This function allows them to utilize user cred ...

The command 'node' is not identified as an internal or external command, executable program, or batch file

While running "npm install node-sass" from git-bash-cli in Windows 10, I encountered a "'node' is not recognized as an internal or external command, operable program or batch file." error. This setup worked fine for years until I upgraded Node t ...