'Proper text scaling with pixi.js?
What am I doing wrong? When I add simple text to my stage, it looks fine on the desktop, but on mobile it renders completely differently (size position etc).
How do I get it to consistently display the same thing on different devices?
The game cannot have a static pixel size, it needs to scale to the browser window size, but keep its aspect ratio.
I set up a complete demo to demonstrate the problem:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
#game {
position: absolute;
}
html,body {
padding:0;
margin:0;
height:100%;
width:100%;
background-color: #000000;
}
</style>
</head>
<body>
<div id="game"></div>
<script src="https://raw.githubusercontent.com/pixijs/pixi.js/master/bin/pixi.min.js"></script>
<script>
var gameElem = document.getElementById('game');
var GAME_WIDTH = Math.max(window.screen.width,window.screen.height);
var GAME_HEIGHT = GAME_WIDTH/16*9;
var renderer = PIXI.autoDetectRenderer(GAME_WIDTH, GAME_HEIGHT,{backgroundColor : 0x000000});
gameElem.appendChild(renderer.view);
// create the root of the scene graph
var stage = new PIXI.Container();
var textOptions = {
font: 'bold 64px Roboto', // Set style, size and font
fill: '#333333', // Set fill color to blue
align: 'center', // Center align the text, since it's multiline
stroke: '#dddddd', // Set stroke color to a dark blue-gray color
strokeThickness: 20, // Set stroke thickness to 20
lineJoin: 'round' // Set the lineJoin to round instead of 'miter'
}
var topText = new PIXI.Text('Some text to do testing!', textOptions);
topText.anchor.x = 0.5;
topText.anchor.y = 0.5;
topText.x = GAME_WIDTH / 2;
topText.y = GAME_HEIGHT / 2-150;
stage.addChild(topText);
autoSetRenderSize(gameElem);
window.addEventListener("resize", function() {autoSetRenderSize(gameElem)});
function autoSetRenderSize(container){
ratio = Math.min(window.innerWidth/GAME_WIDTH, window.innerHeight/GAME_HEIGHT);
stage.scale.x = stage.scale.y = ratio;
var newWidth = Math.ceil(GAME_WIDTH * ratio);
var newHeight = Math.ceil(GAME_HEIGHT * ratio);
renderer.resize(newWidth, newHeight);
container.style.top = (window.innerHeight-newHeight)/2 + 'px';
container.style.left = (window.innerWidth-newWidth)/2 + 'px';
renderer.render(stage);
}
</script>
</body>
</html>
On device with screen resolution of 1920x1080:
On device the screen resolution of 320x480:

This does not happen when you just change your browser size.
Solution 1:[1]
If you want to have 2 totally separate resolutions like that, you cannot rely on 'text scaling' - you just need to have different parameters for your textOptions. Text that is 64px will be fine at a high resolution, but absolutely huge at a low resolution.
A way to cover different resolutions without requireing different settings is to use the resolution settings when creating the renderer.
For example
let renderer = PIXI.autoDetectRenderer( 960, 540, {
resolution: 1
} );
Internally, all of the positioning and size of your game will be to 960x540, and the outputted render will be 960x540.
let renderer = PIXI.autoDetectRenderer( 960, 540, {
resolution: 2
} );
Internally, all of the positioning and size of your game will be to 960x540, and the outputted render will be 1920x1080.
So in this way, you don't have to worry about positioning sprites in different places, and changing the text size; it will automatically handle that for you within PIXI.
Solution 2:[2]
use the Width of the Element as ScaleFactor
var w=280
var h=(w/(16/9))
app = new PIXI.Application({
antialias: false,
width:w,
height:h,
view: document.getElementById("pen-canvas"),
});
demoText= new PIXI.Text('Fit to Canvas',{
"align": "center",
"fontSize":120,
"padding": 25,
"fill": ["#ffffff"]}
);
demoText.anchor.set(0.5);
demoText.x=w/2
demoText.y=h/2
fx= demoText.width/demoText.height
demoText.width =w
demoText.height =w/fx
app.stage.addChild(demoText);
body {
padding: 20px;
background:#fff;
}
<script src="https://pixijs.download/v5.3.7/pixi.js"></script>
<canvas id="pen-canvas"></canvas>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | themoonrat |
| Solution 2 | dazzafact |

