Sign in to follow this  
sergiy-oliynik

Right way to manage stage size for web and mobile

Recommended Posts

I need to have a single code for web and mobile client. I wrote something lie this:

 

var renderer;
var stage;

window.onload = function() {
var w = screen.width;
var h = screen.height;


stage = new PIXI.Container();
renderer = PIXI.autoDetectRenderer(w, h);
document.body.appendChild(renderer.view);
}

In my desktop (FullHD screen) w = 1536, h = 864, window.devicePixelRatio = 1.25, but it work correctly.

In my android device (HD screen) w = 360, h = 640, window.devicePixelRatio = 2. As seen stage has half the size of the actual screen size (720x1280), but stage children has real and correct size(for example image 60x60 realy has 60 pixels). In result my stage content does not fit on the screen.

How to fix it? I need to scale all stage children into ratio? For example: stageChild.scale.x = stageChild.scale.y = 1 / window.devicePixelRatio ? Sorry for my English:-)

Share this post


Link to post
Share on other sites

If you want to have fullscreen then you should use window.innerWidth + window.innerHeight. Screen gives the pixel amount of physical screen, window.inner values give the virtual size used to display the web page.

Share this post


Link to post
Share on other sites
12 hours ago, Exca said:

If you want to have fullscreen then you should use window.innerWidth + window.innerHeight. Screen gives the pixel amount of physical screen, window.inner values give the virtual size used to display the web page.

Thank for answer. window.innerWidth = 360, window.innerHeight = 615, window.devicePixelRatio = 2. My images still doesn't fit in the screen. Do I need to calculate scale coef. and scale all children of stage?

Share this post


Link to post
Share on other sites

Hello sergiy-oliynik,

This is how I do it

1- create a container and append it to the body

2- create your images but add them to the container not the body

3- setup a listener for your onResize , "window.addEventListener("resize", resizeMe); "

4- call the function when you are done loading the page.

inside the resizeMe function , you would take the window.innerWidth and window.innerHeight and scale your stage and resize your renderer

 stage.scale.x = stage.scale.y = somecalculatedratio;

renderer.resize(wwidth, hheight);

 

hopefully this helps you out.

Share this post


Link to post
Share on other sites

Thank to all. 
My code:
 


var renderer;
var stage;

var width = 1280;
var height = 720;

window.onload = function () {
renderer = PIXI.autoDetectRenderer(width, height);
document.body.appendChild(renderer.view);

stage = new PIXI.Stage();

var img = PIXI.Sprite.fromImage('img.png'); // size 1280x720
stage.addChild(img);

window.addEventListener("resize", this.resize);
this.resize();
}

function resize() {
var w = window.innerWidth;
var h = window.innerHeight;

stage.scale.x = w / width;
stage.scale.y = h / height;

renderer.resize(w, h);

width = w;
height = h;
}

Unfortunately, the game scene is scaled incorrectly

Share this post


Link to post
Share on other sites

The stage needs to scale to take into account the difference between the aspect ratio of your target resolution, and the aspect ratio of your browser window. So, if you're targeting 960x540, but the window is at 960x960, then you'll need to set the y scale of your stage to be 0.5626 (540 / 960) to maintain the games correct aspect ratio.

http://www.williammalone.com/articles/html5-game-scaling/ contains a good guide explaining this with code examples (not in PIXI, but easy to transfer)

 

 

Share this post


Link to post
Share on other sites

Since there are a few questions about it elsewhere as well, here is an example of how you could do the resizing after listening to the resize event from the window

function scaleScene(renderer, sceneContainer) {
	const gameWidth = 960;
	const gameHeight = 540;
	const gameOrientation = gameWidth > gameHeight ? 'landscape' : 'portrait';
	const gameLandscapeScreenRatio = gameWidth / gameHeight;
	const gamePortraitScreenRatio = gameHeight / gameWidth;

	const isScreenPortrait = window.innerHeight >= window.innerWidth;
	const isScreenLandscape = !isScreenPortrait;
	const screenRatio = window.innerWidth / window.innerHeight;
	
	let newWidth;
	let newHeight;
	
	if ( (gameOrientation === 'landscape' && isScreenLandscape) || (gameOrientation === 'portrait' && isScreenPortrait) ) {
		if ( screenRatio < gameLandscapeScreenRatio ) {
			newWidth = gameWidth;
			newHeight = Math.round( gameWidth / screenRatio );
		} else {
			newWidth = Math.round( gameHeight * screenRatio );
			newHeight = gameHeight;
		}
	} else {
		if ( screenRatio < gamePortraitScreenRatio ) {
			newWidth = gameHeight;
			newHeight = Math.round( gameHeight / screenRatio );
		} else {
			newWidth = Math.round( gameWidth * screenRatio );
			newHeight = gameWidth;
		}
	}

	renderer.resize( newWidth, newHeight );

	sceneContainer.x = (newWidth - gameWidth) / 2;
	sceneContainer.y = (newHeight - gameHeight) / 2;
}

 

Share this post


Link to post
Share on other sites

I accomplished a little bit of this by using JQuery, you can see the post I made for this here: 

 

The sprites in the container object remain in position and do not change their size when the window is resized. I just use PIXI.WebGLRenderer.resize()

How can I ensure the contents of the stage also scale appropriately?

Share this post


Link to post
Share on other sites
16 hours ago, cnwerb said:

I accomplished a little bit of this by using JQuery, you can see the post I made for this here: 

 

The sprites in the container object remain in position and do not change their size when the window is resized. I just use PIXI.WebGLRenderer.resize()

How can I ensure the contents of the stage also scale appropriately?

Check out the code above, you would need to scale the container that has all the sprites and also resize the renderer.

Share this post


Link to post
Share on other sites
On 12/4/2016 at 11:54 PM, themoonrat said:

Since there are a few questions about it elsewhere as well, here is an example of how you could do the resizing after listening to the resize event from the window


function scaleScene(renderer, sceneContainer) {
	const gameWidth = 960;
	const gameHeight = 540;
	const gameOrientation = gameWidth > gameHeight ? 'landscape' : 'portrait';
	const gameLandscapeScreenRatio = gameWidth / gameHeight;
	const gamePortraitScreenRatio = gameHeight / gameWidth;

	const isScreenPortrait = window.innerHeight >= window.innerWidth;
	const isScreenLandscape = !isScreenPortrait;
	const screenRatio = window.innerWidth / window.innerHeight;
	
	let newWidth;
	let newHeight;
	
	if ( (gameOrientation === 'landscape' && isScreenLandscape) || (gameOrientation === 'portrait' && isScreenPortrait) ) {
		if ( screenRatio < gameLandscapeScreenRatio ) {
			newWidth = gameWidth;
			newHeight = Math.round( gameWidth / screenRatio );
		} else {
			newWidth = Math.round( gameHeight * screenRatio );
			newHeight = gameHeight;
		}
	} else {
		if ( screenRatio < gamePortraitScreenRatio ) {
			newWidth = gameHeight;
			newHeight = Math.round( gameHeight / screenRatio );
		} else {
			newWidth = Math.round( gameWidth * screenRatio );
			newHeight = gameWidth;
		}
	}

	renderer.resize( newWidth, newHeight );

	sceneContainer.x = (newWidth - gameWidth) / 2;
	sceneContainer.y = (newHeight - gameHeight) / 2;
}

 

What is sceneContainer in this code? Is it just the PIXI Container object?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.