Three.js Window Resize: How to Update Canvas

In Three.js, responsive design is crucial for maintaining a seamless user experience across different devices and screen sizes. This article provides a straightforward guide on how to handle window resize events to dynamically update your Three.js canvas, ensuring your 3D scene remains perfectly proportioned and distortion-free when a user resizes their browser.

To keep your Three.js canvas responsive, you must listen for the browser’s resize event and update three main components: the camera’s aspect ratio, the camera’s projection matrix, and the renderer’s size.

Here is the standard implementation code:

// 1. Listen for the window resize event
window.addEventListener('resize', onWindowResize, false);

function onWindowResize() {
    // 2. Update camera aspect ratio
    camera.aspect = window.innerWidth / window.innerHeight;
    
    // 3. Update the camera's projection matrix
    camera.updateProjectionMatrix();

    // 4. Update the renderer size
    renderer.setSize(window.innerWidth, window.innerHeight);
    
    // 5. Optional: Update pixel ratio for high-DPI screens
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
}

Step-by-Step Breakdown

1. Add the Event Listener

The window.addEventListener('resize', ...) method ensures that the onWindowResize function is triggered every time the browser window dimensions change.

2. Update the Camera Aspect Ratio

The camera’s aspect ratio is calculated by dividing the width of the viewport by its height (window.innerWidth / window.innerHeight). If you do not update this value during a resize, your 3D objects will appear stretched or squished.

3. Update the Projection Matrix

Modifying the camera’s aspect ratio does not automatically apply the changes to the rendering engine. You must call camera.updateProjectionMatrix() to force Three.js to recalculate the camera’s viewing frustum with the new aspect ratio.

4. Update the Renderer Size

The renderer.setSize() method resizes the HTML <canvas> element to match the new width and height of the window. This ensures the canvas fills the entire screen and matches the new viewport dimensions.

5. Handle Device Pixel Ratio (Optional)

On high-DPI (Retina) displays, updating the pixel ratio keeps the rendering sharp. Using Math.min(window.devicePixelRatio, 2) improves performance by capping the rendering resolution at a pixel ratio of 2, preventing unnecessary rendering overhead on extremely high-resolution screens.