Expanding Three.js Canvas Size

I've been immersed in a 3D project where we showcase 3D objects in a web browser using the Three.js Library.

One major issue has cropped up:

  • Initially, the model appears small within a dom element or when the browser window is resized to a smaller size.
  • Upon resizing the window (or the dom element), the model starts to appear pixelated and loses its crispness.

Here are some snapshots showcasing this problem:

Before resizing:

After resizing:

How it ideally should look after resizing:

The following code snippet determines the dimensions (height and width) of the model, and is executed upon triggering the resize event:

console.log("domChanged fired")

instance.domBoundingBox = instance.dom.getBoundingClientRect();
instance.domCenterPos.x = instance.domBoundingBox.width / 2 + instance.domBoundingBox.left;
instance.domCenterPos.y = instance.domBoundingBox.height / 2 + instance.domBoundingBox.top;

var width = instance.dom.clientWidth, height = instance.dom.clientHeight;
instance.domWidthHalf = width / 2, instance.domHeightHalf = height / 2;

// TODO: emit an event to make it accessible for site developers

// updating various values related to width, height, and position here
if(instance.cameraReal) {
    instance.cameraReal.aspect = instance.dom.clientWidth / instance.dom.clientHeight;
    instance.cameraReal.updateProjectionMatrix();
}

if(instance.renderer3D)
    instance.renderer3D.setSize(instance.dom.clientWidth, instance.dom.clientHeight);

Could anyone provide any insights? I've been at it for a few days now with no breakthrough so far.

Answer №1

Just like any other element, the canvas element can also be resized. To ensure that your canvas content adjusts to the new size, you need to update both the render and camera.

window.addEventListener( 'resize', resizeCanvas, false );

function resizeCanvas(){

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

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

}

Answer №2

The problem was finally resolved after discovering that it originated from the application's use of the THREE.EffectComposer object. In the class constructor, a composer object was created like this:

this.composer = new THREE.EffectComposer(this.renderer3D);

It was realized that, just like the renderer, the composer needed its size to be updated after an event handler function, as shown below:

if(instance.renderer3D)
    instance.renderer3D.setSize(instance.dom.clientWidth, instance.dom.clientHeight);
if(instance.composer)
    instance.composer.setSize(instance.dom.clientWidth, instance.dom.clientHeight);

This simple adjustment successfully resolved the issue :)

Answer №3

I implemented Shawn Whinnery's solution in my React JS project:

Start listening for changes when component mounts:

componentDidMount() {
  window.addEventListener('resize', this.handleResize, false)
}

Stop listening for changes when component unmounts (to help with garbage collection):

componentWillUnmount() {
  window.removeEventListener('resize', this.handleResize, false)
}

Set up the handler function:

handleResize = () => {
  this.camera.aspect = window.innerWidth / window.innerHeight
  this.camera.updateProjectionMatrix()
  this.renderer.setSize(window.innerWidth, window.innerHeight)
}

We use fat arrow syntax to avoid binding issues with this. If you prefer using regular function syntax like handleResize() { ... }, make sure to bind it in your constructor:

this.handleResize = this.handleResize.bind(this)

Note: Make sure that this.camera refers to your camera object and this.renderer refers to your renderer instance. With those checks in place, you should be able to integrate this code seamlessly.

Answer №4

If you're in search of a quick solution to resizing, look no further than this handy utility that takes care of it for you. Take a peek at this repository on GitHub: https://github.com/jeromeetienne/threex.windowresize

All you need to do is install it using bower and then initialize it like so:

new THREEx.WindowResize(renderer, camera)

Answer №5

Consider using the antialias property to reduce pixelation issues by 50-70%.

For example:

var engine = new THREE.WebGLRenderer({antialias:true});

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 is the purpose of employing useMemo in the Material-UI autocomplete documentation?

My focus is on this specific demo in the autocomplete documentation. In the google maps example, there is a throttled function that is returned from a useMemo with an empty array as the second parameter. However, it raises the question of what exactly is ...

Setting the height of content using jQuery can be a useful solution when dealing with small window sizes to prevent it from

Encountering an issue with this code. It currently resizes section[role="main"] to the proper height but cuts off when the window is resized to a smaller size. <script type="text/javascript"> $(function(){ $('section[role="main"]&ap ...

When incorporating Typescript into HTML, the text does not appear in bold as expected

Issue with bold functionality in Typescript Hey there, I am currently involved in an Angular project and I came across a problem with a function in a Typescript file that is supposed to bold a specific segment of text formatText() { ......... ...

Is there anyone out there who has successfully imported a model from the three.js editor?

As a designer and 3D artist who occasionally delves into coding, I have a question regarding loading a model from the three.js editor into an actual web page. Despite my limited programming knowledge, I've tried various methods to achieve this, includ ...

Handling exceptions in Express.js with EJS templating using Node.js

I have encountered an issue with routing while developing my first node.js/express web-app. I suspect it has something to do with the way I am connecting the router in Express 4. Here is some debug information related to the problem: var router = express ...

How can I assign a distinct background color to individual sections in Chart.js?

Wanting to Customize Grid Background Colors in Line Chart using react-chartjs-2 I am looking to have different background colors for each grid in my Line chart. Is this functionality possible with the react-chartjs-2 library? This is the desired appearan ...

Tips for sending values as parameters to a function within an onclick event in Angular2 without using ngClick

In my Angular2 project, I am facing an issue with passing values from an *ngFor loop as a parameter to a function call on the (click) attribute event in my anchor tag. This is because calling functions using onclick is not allowed for security reasons. He ...

Sending a `refresh` to a Context

I'm struggling to pass a refetch function from a useQuery() hook into a context in order to call it within the context. I've been facing issues with type mismatches, and sometimes the app crashes with an error saying that refetch() is not a funct ...

`Express.js Controllers: The Key to Context Binding`

I'm currently working on a project in Express.js that involves a UserController class with methods like getAllUsers and findUserById. When using these methods in my User router, I have to bind each method when creating an instance of the UserControlle ...

Is there a way to prompt the user to enable their Bluetooth functionality using JavaScript?

Currently working on a web application that requires the user to enable their Bluetooth connection once the app is loaded. I plan to implement a pop-up message asking the user to turn on their Bluetooth, and if they click "OK", their Bluetooth will be ac ...

Transferring data seamlessly between AJAX and PHP

<?php //Establishing site root variable; ?> <?php require_once("../includes/site_init.php"); ?> <!DOCTYPE HTML> <html lang = "en"> <head> <meta charset = "UTF-8"> <meta name = "viewport" content = "width ...

"Exploring the dynamic manipulation of CSS display property through the use of an active class

When attempting to implement a small pop-up window for user confirmation before navigating away from the page, I encountered an issue. Upon clicking the RUN button with the id "openBtn," the pop-up window briefly appears and then disappears. I'm unsur ...

I need to convert a Json date to a date object, but the server's timezone is causing the time to change. I need to ensure the date and time zone remain consistent

this.convertJSON_DateTimeTo_datetimeObj = function (jsonDate) { var date_dd_MM_yyyy = $filter('date')(jsonDate.slice(6, -2), 'medium'); //var dt = new Date(date_dd_MM_yyyy).toLocaleString("en-US", { tim ...

Removing/modifying selected choices in an element

I have implemented a material ui select element with the ability to make multiple selections using checkboxes. My query is, can I incorporate the functionality to delete or update names directly from the select element itself? For instance, by clicking on ...

Can you identify the target of the term "this" in the upcoming JavaScript code?

DISCLAIMER: I am inquiring about a specific instance of this, not its general purpose. Please refrain from quick Google responses or copied answers (: The code snippet below demonstrates JavaScript/jQuery: var req = {}; function getData() { var from ...

Is there a method to retrieve all Class elements without using a for-loop?

I am trying to retrieve all elements with a specific class using document.getElementsByClassName(); <body> <div class="circle" id="red"></div> <div class="circle" id="blue"></div> <div class="circle" id="yell ...

Fetching JSON Data from Web Service using Ajax URL Field - A Simple Guide

I'm facing an issue while attempting to retrieve JSON Data from a web service using ajax url. This is how I have coded it so far: <script type="text/javascript> $('#kategoriTable').dataTable({ ajax: { u ...

What is the best way to forward a client to a different page using an Express post route?

I am currently working on a node/express web application where I have a button that, when clicked, transforms a <div> into a pdf, zips and secures the pdf with a password, sends it via email to the recipient, and finally generates a new page displayi ...

Resizing Bootstrap Modal using React with a Personalized Dimension

Is there a way to manually set the width of Bootstrap's Modal React component on my website? I want to be able to define the width in pixels, and if possible, use a const object in the .jsx file for CSS. If not, I can resort to using a .css file. Be ...

onpageshow event behaves as expected exclusively on webkit browsers (triggers function solely when visible on the screen)

I am inserting an HTML file using an object tag. The encompassing div of the object tag is hidden with a display:none property. However, I encounter an issue where the onpageshow event that I placed on the body tag of the HTML object behaves differently a ...