Godot and HTML5

Maintain Aspect Ratio with Godot HTML5 Export

Recently, we had a break from the usual web development to produce a Godot edutainment game. The 2D game is available on Android, iOS and HTML5.

Our game was produced to display at 1080p screen resolution, but we wanted the game to scale. This is fine on smartphones and tablets, because you can limit the display to Landscape mode. However, HTML5 presents a problem.

At this time, the HTML5 Canvas Resize Policy in Godot only offers 3 options. None, Project (1080p) or Adaptive (fill the entire browser). I wanted the game to take up the full browser width or height, but maintain a 16:9 aspect ratio, while also remaining centred on the screen.

What I found worked best, was to set the Canvas Resize Policy to ‘None’, as suggested by the Godot docs. Trying to do this with CSS alone resulted in a blurry game. Using JavaScript on window resize triggers the Godot scripts to update the canvas.

Paste the script below in the Head Include:

<!-- Center canvas in the window. -->
<style>
#canvas {
    margin: auto;
    padding: 0;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}
</style>
<!-- Resize canvas to maintain 16:9 aspect ratio. -->
<script>
window.addEventListener( 'resize', () => {
    const canvas = document.getElementById( 'canvas' );
    const windowWidth = window.innerWidth;
    const windowHeight = window.innerHeight;
    const height = ( windowWidth / 16 ) * 9;

    if ( windowWidth < windowHeight ) {
        canvas.width = windowWidth;
        canvas.height = height;
        return;
    } else if ( windowWidth > windowHeight && height > windowHeight ) {
        canvas.width = ( windowHeight / 9 ) * 16;
        canvas.height = windowHeight;
        return;
    }
	
    canvas.width = windowWidth;
    canvas.height = height;
} );

window.addEventListener( 'DOMContentLoaded', () => {
    window.dispatchEvent( new Event( 'resize' ) );
} );
</script>