Game Safe Area Window

I’ve looked around at several of the scale manager examples in Phaser 3 here: https://labs.phaser.io/index.html?dir=scalemanager/&q=

But I’m not coming across the desired result. I’m looking for something similar to this: http://www.williammalone.com/articles/html5-game-scaling/

I want my game to be centered, and to have a min/max width/height bounds. When I try using the fit min/max, I can’t center my game.

Anyway to do this?

You might try:
scale: { mode: Phaser.Scale.ScaleModes.HEIGHT_CONTROLS_WIDTH }
autoCenter: Phaser.Scale.CENTER_BOTH

Although the demo at the end there looks to work more like Phaser.Scale.ScaleModes.FIT which shows all but keeps aspect ratio and therefor does not always use the full available space.

To get the expected behaviour, you need to use:

scale: {
            mode: Phaser.Scale.FIT,
            autoCenter: Phaser.Scale.CENTER_BOTH
        },

and a dedicated function to ensure the right behaviour according to the window aspect ratio:

function resizeApp()
{
    // Game settings
    var game = {
        width: 1920, // default game width
        height: 1200, // default game height
        safeWidth: 1024, // minimum width visible
        safeHeight: 768, // minimum height visible
        container: document.getElementById("app")
    }
    	
    // Get the dimensions of the viewport
    var viewport = {
        width: window.innerWidth,
        height: window.innerHeight
    };

    var newGameWidth, newGameHeight, newGameX, newGameY;
    
    // Determine game size
    if (game.height / game.width > viewport.height / viewport.width) 
    {
        if (game.safeHeight / game.width > viewport.height / viewport.width) 
        {
            // A
            newGameHeight = viewport.height * game.height / game.safeHeight;
            newGameWidth = newGameHeight * game.width / game.height;
        } 
        else
        {
            // B
            newGameWidth = viewport.width;
            newGameHeight = newGameWidth * game.height / game.width;
        }
    } 
    else
    {
        if (game.height / game.safeWidth > viewport.height / viewport.width) 
        {
            // C
            newGameHeight = viewport.height;
            newGameWidth = newGameHeight * game.width / game.height;
        } 
        else 
        {
            // D
            newGameWidth = viewport.width * game.width / game.safeWidth;
            newGameHeight = newGameWidth * game.height / game.width;
        }
    }
  
    game.container.style.width = newGameWidth + "px";
    game.container.style.height = newGameHeight + "px";
			
    newGameX = (viewport.width - newGameWidth) / 2;
    newGameY = (viewport.height - newGameHeight) / 2;
			
    // Set the new padding of the game so it will be centered
    game.container.style.margin = newGameY + "px " + newGameX + "px";
}

// Scale to device
window.addEventListener('resize', resizeApp);
resizeApp();

I tried both ideas, but it still failed on my side. Am I missing some CSS maybe? Is there a method to resize the canvas element?

This should be sufficient:

{
  scale: {
    parent: 'PARENT',
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH,
    width: 800,
    height: 600,
    min: {
      width: 800,
      height: 600
    },
    max: {
      width: 1600,
      height: 1200
    }
  }
}

If it’s not working, open your DOM inspector and look at the styles for canvas, parent, body, and html.

Here is a fully working example with the code provided by @CaptainTurtle

Edit: I have made 2 examples. One with a FULL mode and the other with a FIT mode. Check both!

FULL mode

FIT mode

1 Like

I have made an even better example with a safeArea. In the above two examples the canvas stays always the same size, only the margin of the css changes.

In the example I posted here, the canvas will also scale.

1 Like

This is exactly what I was looking for, thank you everyone!