Explain Codes LogoExplain Codes Logo

Resize HTML5 canvas to fit window

javascript
responsive-design
performance
best-practices
Anton ShumikhinbyAnton Shumikhin·Nov 1, 2024
TLDR

To scale the HTML5 canvas to fit the window, you can simply listen to the resize event of the window and dynamically update the canvas width and height properties to window.innerWidth and window.innerHeight respectively.

window.addEventListener('resize', () => { const canvas = document.getElementById('myCanvas'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; }); // Capture the Moby Dick of screen spaces, the full window width and height! document.getElementById('myCanvas').width = window.innerWidth; document.getElementById('myCanvas').height = window.innerHeight;

With this code snippet, your canvas will be as full-screen as a Hollywood blockbuster on opening night — set to go right on page load and resizing with every change in window size.

Aspect Ratio: Keeping your shapes in shape

For an attractive canvas display without any grotesque distortions, maintaining aspect ratio is the holy grail. You would need to factor this in when defining your dynamic resizing function. Here's how:

function resizeCanvas() { const canvasAspectRatio = canvas.width / canvas.height; const windowAspectRatio = window.innerWidth / window.innerHeight; const width = window.innerWidth; const height = width / canvasAspectRatio; // Aspect ratio, meet your matchmaker! if (windowAspectRatio < canvasAspectRatio) { canvas.width = window.innerHeight * canvasAspectRatio; canvas.height = window.innerHeight; } else { canvas.width = width; canvas.height = height; } }

Resize like a Pro with ResizeObserver

Upgrade your resizing game to professional level with ResizeObserver. This API is like your personal canvas size detective, providing efficient and precise monitoring of your canvas dimensions. Let's set it on a mission!

const ro = new ResizeObserver(entries => { for (let entry of entries) { const cr = entry.contentRect; canvas.width = cr.width; canvas.height = cr.height; } }); // Whispering in ResizeObserver's ear, "Observe my canvas please." ro.observe(document.getElementById('canvasContainer'));

Going Retina: Catering to high-DPI displays

To ensure that your canvas doesn't disappoint on high-DPI (Retina) displays, you've got to respect the devicePixelRatio. Let's make our canvas the belle of the Retina display ball:

function resizeCanvas() { const ratio = window.devicePixelRatio; const width = window.innerWidth * ratio; const height = window.innerHeight * ratio; canvas.width = width; canvas.height = height; canvas.style.width = `${window.innerWidth}px`; canvas.style.height = `${window.innerHeight}px`; const ctx = canvas.getContext('2d'); // Entering the Matrix! Scaling canvas to Retina display glory. ctx.scale(ratio, ratio); }

Bye scrollbars! Set display: block

Scrollbars can be an unwanted guest at your full-screen party. Send them packing by setting your canvas to display: block. Pro tip: Scrollbar eviction notice delivered via CSS:

canvas { display: block; }

And, why stop there? Why not take over the entire space of html and body as well to display your canvas in all its full-screen glory:

html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; /* Now where are you going to scroll? */ }

Minimize Redraws: Don't repaint the Mona Lisa!

Repeated redrawing of your canvas can hit performance like a sledgehammer. To avoid turning your graphical masterpiece into a crawl-space, minimize redraws upon resizing. If you must reposition elements on resize, cache their positions for the grand performance.

Verifying Visual Accuracy: Is your canvas the perfect fit?

Debugging canvas alignment and size is often achieved via a strategic border. Here's how to visually verify your canvas's fitting:

canvas { border: 1px solid #000; /* They say seeing is believing */ }

Once in the clear, you're ready for borderless beauty!

Scaling Dilemma: JavaScript-based sizing vs viewport units

While it might seem attractive to use viewport units to size the canvas through CSS, dynamic changes due to different factors may leave your canvas feeling inadequate. Thus, JavaScript-based sizing, is the way of the canvas Jedi.