How to size image to fill its container while maintaining aspect ratio (using svg as source)?

I’m struggling a bit to manage the size and fill of a GUI Image control. Can anyone offer some insight? Also, please note that we are still on an older version of Babylon.

Babylon version: 5.57.1
Playground example

I want the image to fill the width of the its parent container, the StackPanel, and automatically size it’s height to maintain its aspect ratio. What am I missing here?

NOTE: The link to the SVG file is in the playground source code. I included the original URL (which doesn’t work in the playground) as well as the Dropbox download link that is working in the sandbox. View this SVG to get an idea of what it should look like.

Ok it seems linked to the SVG resolution done by the browser

This is not related to the StackPanel as the problem occurs even with just the image:
Babylon.js Playground (babylonjs.com)

If you reduce the size of the rendering window you can see the SVG appearing…

Whereas no problem with regular image:
Babylon.js Playground (babylonjs.com)

Digging it more deeply…

Temporary fix:
Babylon.js Playground (babylonjs.com)

We have to force the domImage into the dom to ensure the SVG size is properly computed

You can do that in your case.

I will fix that behavior on the main framework

Main fix: Fix SVG loader for GUI by deltakosh · Pull Request #15181 · BabylonJS/Babylon.js (github.com)

@Deltakosh What are properties need to be set for the image to size itself and maintain its aspect ratio but without knowing the original size ahead of time? This has to be a common use case so I feel like I missing something obvious.

I switched my playground example from SVG to JPG to eliminate any possible issues related to SVG handling. Could you please take a look at this playground example as well?

JPG Playground Example - Babylon 5.57.1

Desired Behavior:

  • Vertical StackPanel is a fixed width
  • Vertical StackPanel’s height adapts (shrinks) to its children
  • Image control fills the width of the StackPanel, so width = 100%
  • Image control determines its own height
  • Image control maintains the image’s original aspect ratio
  • This behavior works without knowing the original size of the image

Property value autoScale = true seems to override other size properties including widthInPixels. This causes the image to grow larger than desired, but it does size its height properly based on width. But so I assume this needs to be false.

Property value image.stretch = STRETCH_UNIFORM is the behavior I desire because it says it fills while maintaining aspect ratio. However, the height always seems to end up at a value of 100%. Therefore the StackPanel thinks the image control’s height is 0px and the entire things is clipped.

Adding property value fixedRatioMasterIsWidth = true did not affect the height, even if I explicitly set the width to 280px instead of 100%. This property looked promising but didn’t fix my issue. The height still gets calculated to 100% and the image is not visible in the StackPanel.

I also experimented with the same properties above but with a width explicitly defined in pixels. Some results were different but never got height to have a value other than 100% unless I explicitly set the height but that’s not possible since I don’t the size before creating the image control.

Please note that my team is using BabylonJS 5.57.1 so that’s the version set in the playground. However, switching to the latest in the playground doesn’t change the result.

This can’t be that complicated. What am I missing?

sorry I’m on vacation for 2 weeks.Let see if @RaananW can have a look for me :wink:

2 Likes

Thanks @Deltakosh, hope you enjoy the vacation!

@RaananW Let me know if you have any tips or suggestions to solve the image sizing issues I’m experiencing. Thank you!

1 Like

The GUI itself will have hard time doing that, as this feature is not (yet?) available. It can be done using code though:

    image.onImageLoadedObservable.add(() => {
        image.heightInPixels = image.widthInPixels * (image.imageHeight / image.imageWidth)
    })

GUI Image Control: Auto size and scale | Babylon.js Playground (babylonjs.com)

Of course, this should run on each window resize, to be sure the image maintains its aspect ratio (or even on each frame, if it is not too expensive).

The problem is a known issue in UI design - you have a container, a vertical stack that adapts its height from its children. If the child doesn’t have height defined, then the container will not grow, and thus - the child will not be shown. An argument can be made that an image container is quite special, as we CAN get its height, relative to the current width in pixels, and, TBH, i wouldn’t argue against it :slight_smile: It’s just that it isn’t implemented. Until it is, code is the way to go.

Thank you for this insight @RaananW! We are doing some special rendering process so this didn’t work in our project (due to the timing of when we move a UI from screen space to world space), but this clearly works in the Playground.

We were able to resolve the issue in our project. Thanks again!

2 Likes