How to set and load your assets on different screen resolutions using JavaScript and PixiJS
On today’s post I’ll explain how to check the devices’ resolution, how to define a scale factor and how to set and load the assets related with graphics (atlases and layouts) depending on which resolution we need the graphics being displayed.
How to get the device resolution
Initially, the resolutions I was facing on this case (in landscape mode) were Full HD (1920x1080px), HD Ready (1280x720px) and a custom Low Resolution (760x480) which was the project’s original base resolution. In the end, due to the tests I did with several devices and screens, and overall for the designer’s atlases management simplicity, I’ll stick with two resolutions: Low Resolution and Full HD, that means Full HD graphics will be loaded for HD Ready’s case too.
Is that wrong? Depending on your project needs, both approaches can be right, but remember that for each native resolution you support, you need to mantain a new version of your graphics on that size, so if the designer makes a style modification on a graphic element, the atlases need to be exported again in all the resolutions you’re using, this shouldn’t be a problem, but if your designer is facing with a design which has been made in Flash a bunch of years ago, trust me it’s not a trivial thing.
So, when are we supposed to load low resolution graphics and when the Full HD graphics? Basically, all smartphone devices will load low resolution graphics whereas devices with a minimum width of 1024px, that is to say tablets, will load the full hd graphics version. The following script returns if we need to load FullHD or LowRes graphics:
Why are we checking both width and height?
Let’s check some devices resolutions examples on landscape mode using console.log:
console.log('Screen resolution: '+screen.width+'x'+screen.height+' . Pixel ratio: '+window.devicePixelRatio);
ipad 3 -> Screen resolution: 768x1024. Pixel ratio: 2
iphone SE -> Screen resolution: 320x568 Pixel ratio: 2
samsung S5 -> Screen resolution: 640x360 Pixel ratio: 3
PC screen -> Screen resolution: 1920x1080 Pixel ratio: 1
samsung galaxy tab -> Screen resolution: 600x1024 Pixel ratio: 1
As you can see, some devices return the measurements in landscape mode and others on portrait, that’s why we need to check both width and height.
What is pixel ratio and why do we need it?
On the following post you can learn about pixel ratio: https://stackoverflow.com/questions/8785643/what-exactly-is-device-pixel-ratio
And on this link you can see a list of devices with its physical measurements, CSS measurements and pixel ratio: https://mydevice.io/devices/
Taking this into account, the data we previously got using console.log returns the CSS width and height, and the pixel ratio, if you multiply those values:
CSS_width X pixel_ratio = physical_width
CSS_height X pixel_ratio = physical_height
You get the physical measurements of the device, so in the case of devices such as tablets we want to load the Full HD graphics if they match this case:
CSS_width ≥ 1024px && pixel_ratio ≥ 2
Otherwise, there’s a very small difference on screen between loading Full HD graphics or Low Resolution but the performance is worse with Full HD graphics due to most of those devices being old-fashioned.
How to define a scale factor
The following step is having a reference in the code to the scale factor, why do we need this? For example, if you manually place paddings or margins to texts generated by Pixi, you need to multiply the value of the padding to the scale factor of the current resolution used, otherwise the padding will look good on one of the resolutions but terribly out of place in the rest of resolutions.
On this case, the Full HD scale factor is 2.25, but this is related to this particular case, it is not a “standard” value to use.
How I manage to load the graphical assets?
First, we need an assets.json file with a structure similar to this one:
This file contains the path to the project’s atlases files, the atlases contain the images of the project in a whole png, and the json contains the positions of each image, so the code can get each image from the png.
We also have a layout.json, this file contains the positions where the images from the atlas are supposed to be placed in our application or game, with the following script we can load the needed layout for our current resolution:
And with the script below, we can load the suitable atlases files:
So this is the basics on how we can handle the management of graphic assets depending on the device’s resolution we need to load, I hope you find it useful :)