Any way to make the camera zoom/FOV "responsive" behavior the same on horizontal resize as it is on vertical resize?

I’ve noticed that when the canvas is resized vertically, the camera (maybe more accurately the camera’s zoom or FOV?) will responsively adjust so that the scene still stays within view, but the behavior when resizing horizontally is different: the camera (or zoom/FOV?) stays the same but the render just clips off the sides of the canvas.

Is there a way to have the camera zoom/FOV behavior be the same for resizing in both directions, so that changing the width of the canvas also zooms the scene in/out to keep everything in frame? My initial thought is that ideally it would take whatever is the minimum between the height and the width, and scale the camera/FOV based on that, just to ensure the scene always stays in frame.

Here’s a video of the playground in action, showing how the ground plane and sphere shrink and grow with the canvas when the height is resized, but clips off the left and right sides when the width is resized:

And here is a video of the desired behavior, where the scene always stays in frame no matter how the canvas is resized (this is just a static image in this video, and it uses CSS’s background-image: contain; to simulate the responsive behavior):

Thanks for any help! :grin:

Hi @Billy, welcome aboard :beers:
Something like this?

2 Likes

Thanks for the welcome, and an even bigger thanks for that playground link! That’s the exact behavior I was looking for.

Just so I’m understanding exactly how it’s working, is the key here the resize listener on line 18 that calls both engine.resize() and the framing behavior settings that are defined in the fitToCanvas() function? In other words, both of those are required to make this work?

Again, thanks so much! I’ll try this out on my project now. :slight_smile:

1 Like

Yes, you need to call the framing behavior inside resize event.

Hi @MarianG, I think I might’ve spoke too soon, I ran into an issue. :sweat_smile:

I’ve updated your playground example here and noticed that framingBehavior actually resets the camera zoom entirely when the window’s height is resized:

https://www.babylonjs-playground.com/#TT2BK1#26

The behavior I’m hoping for is to keep the current zoom level consistent as the canvas/window resizes, but still be responsive in both directions (BJS’s camera already behaves this way vertically by default but not horizontally), basically like this video but respecting the current zoom level too:

It seems like the Babylon camera is already has some logic to recalculate a new FOV/zoom level to keep the same apparent perspective and zoom whenever the window’s height is resized. Any hunches on how to reproduce that same logic for width resizes too?

Again, I really appreciate all your help so far. :slight_smile:

Hi, I understood. Let me ping @carolhmj maybe she has a better idea

You can try to change the camera fovMode property:

It switches to “horizontal fixed” when the change in width is greater than the change in height, but as you can see, this is not very good because there’s a “hiccups” when we switch from one mode to the other.

3 Likes

Hello @Billy apologies for not seeing this earlier? Did Popov’s suggestion of changing fovMode help you?

1 Like