How to get Aspect Ratio of Zappar app screen?

I found this snippet that was shared by @Seb but having trouble understanding how it works because I’ve put in the snippet in my script and assigned the aspectRatio value to a Text so i can see it on screen and the devices I’ve tested on have always returned 1 although i can clearly see that my on-screen buttons are cropped at the top and at the bottom. Really need some guidance on this. Thanks in advance.

It definitely seems to work ok here - I’ve used it to scale a 3D object so it matches the screen ratio. Did a quick test just now, and it seems to return plausible values. The code I used:

let aspectRatio : number;
Z.screen.on("resize",(height,width)=>aspectRatio = height/width);

const ar = symbol.nodes.ar;    // text symbol to display aspect ratio value

parent.on("show", () => {
    ar.text(aspectRatio.toString());

...

It may help to pop a snippet of your code up here, or a bare-bones project so we can have a nose at it

Does it display different values? cause so far i’m just getting 1, what values do you get? and yeah that’s the snippet I’m using. does it matter where this line is placed?

ar.text(aspectRatio.toString());

Yep - ! get 1.602803… on my iPhone, 1.40… if I launch in the desktop Zappar app thingie.

That ar.text(blahblah) line just needs to be somewhere it’ll get run after the resize function is triggered. Putting it in one of the show handlers seems to work

(I’m pretty new to all this: haven’t yet needed to investigate the order events get fired off, but this worked first time for me. Yay for beginner’s luck, I guess)

Ah… i see. thanks! such a noob, should’ve tried putting that specific line in an event handler. new to zappar as well! will try this and hopefully come back with good news.

:slight_smile: I guess that if it’s not in an event handler then it runs immediately on launch, which will be before any event handlers – including the on resize one – have run.

All this event handler stuff, and “where should I put this bit of code because there are so many places you can add scripts” thing - it’s giving me flashbacks to the few years I spent playing with Adobe Flash back in the day. At some point it’s all gonna click, but until then I’m trying to keep my code to myself because although I seem to be able to get things working OK, it feels like I’m doing things in a roundabout “bad code smell” way :slight_smile:


Turns out the Z.screen.on(“resize”… thing will actually return the pixel size of the frame, which could be useful.

let aspectRatio : number;
let myheight : number;
let mywidth : number;

Z.screen.on("resize",(height,width)=>{ 

    aspectRatio = height/width;
    myheight = height;
    mywidth = width;

})

const ar = symbol.nodes.ar; //text symbol

parent.on("show", () => {

    ar.text("ar = "+aspectRatio.toString() + ", h = " + myheight.toString() + ", w = " + mywidth.toString());

...

11

2 Likes

Thank you for the insight. works.

Oh hey. Awesome. Thanks so much for sharing

Hey @howiemnet , i need to resize a plane according to aspect ratio but currently it’s “in a roundabout “bad code smell” way” :sweat_smile: using if-else statement by comparing the returned values. how would i go about doing it dynamically?

Ever since I first heard someone refer to a chunk of code as “having a bad code smell about it” it’s kinda stuck :slight_smile:

There’s nothing intrinsically wrong with using if/else logic to choose how to handle different ratios. You say “dynamically”, though; are you trying to trigger something if the aspect ratio changes (eg if a user rotates their phone)? If so, you may want to add an accelerometer node to your project - as I understand it, it’ll fire off an event (or trigger a state change if you like) when a phone’s rotated. Haven’t yet played with it, but there’s more info here. There’s also this page on UI Coordinate Systems that may be useful.

Just trying to make all the on-screen UIs position nicely on screen for different screen sizes. Like i said, im using if-else and feel i might end up with endless statements haha. like for example, there are buttons that i want to stay put at the bottom of the page but depending on the screen size itll look like theres too much gap between the bottom of the screen and the buttons itself. wish there was some sort of anchoring for UIs like in Unity

Gotcha. You can position stuff so it anchors to the bottom of the screen: in Z.screen space, the bottom of the screen is always at y = -1, so if you put your buttons in a group, make sure they’re positioned so they’re just above the group’s origin (with their “Relative To” set to the group), then position the group itself at y = -1, the buttons will always end up at the bottom of the screen.

But yep, procedural approaches can’t always get you all the way to aesthetic perfection… (don’t get me started on kerning or you’ll be here all night)

Oh. this is helpful. so to clarify put buttons in a group. the buttons “Relative To” set to the group. group position at -1. “positioned so they’re just above the group’s origin”, so 0? if the group is -1 then just above is 0?

*still abit confused on how to use Relative To :sweat_smile:

:slight_smile: It’ll probably make sense if you have a play with it - but yep, it can get a bit convoluted. If you have a group set Relative To Z.screen, with a position of y = -1, then you can put stuff in the group and it’s as if they have a new coordinate system starting with y = 0 at the bottom of the screen.

So if you had a button centred at 0,0,0, but you stick it in that group, it’ll now be centred round the bottom of the screen. That’s probably not exactly what you need - you want things to appear above the bottom of the screen. So you’d want to raise the button up enough so it doesn’t get cut off…

The reason it’s useful to have this group arrangement, though, is that once you’ve positioned all your buttons so they’re just above the ground-level of the group, you can scale the group itself up or down, bigger and smaller, and the scaling now happens from the bottom of the screen, rather than the centre.

Inside the group, you have a new origin point, effectively, and that helps enormously with dynamic positioning, scaling etc

1 Like

My image tracking is flat so the coordinates are switched. so instead of -1 i used 1 instead. still not stuck to the bottom of the screen. Though my button group is in another group. does that effect?

You’d want your button group to be Relative To Z.screen, and make sure that the buttons inside the group have no “Relative To” set, so they’ll use their parent’s(ie the button group’s) coordinate system.

1 Like

Hey @howiemnet Thanks for sharing this code.
I am having issues trying to get it working

  • When I copy and paste either bit of code into a blank project (with only a text symbol in the hierarchy) I get an error on either of the last lines - Both highlight the last semicolon and state ‘)’ expected.

ar.text("ar = "+aspectRatio.toString() + ", h = " + myheight.toString() + ", w = " + mywidth.toString());
ar.text(aspectRatio.toString());

I tried adding }) to the end of the block of code to close the ‘()’ which eliminated the error, but I’m getting no text return on the screen when I preview the project.

I a definite noob when it comes to code… Any help would be greatly appreciated!
Or perhaps share a .zpp with the code in it?

Aspect Ratio.zpp (187.7 KB)

I’m attempting to do the same as Nadia, resize UI elements based on the aspect ratio,