Device orientation and (scene/window) resize on iOS/Safari

I’m not much of a mobile app worker so my issue could also be a simple html/css issue (or could/should be fixed this way) I don’t know.

My problem is that whenever i change the orientation (say on iphone) from portrait to landscape or the other way round, I get a blank space below my scene/canvas that seems to match the size of the Safari toolbar. What am I likely missing here?
Thanks in advance for your valuable and much appreciated input…
Meanwhile, have a great day,

1 Like

I would think it is all CSS related, but a repro would be great and our friend @RaananW is definitely a huge CSS fan :slight_smile:

1 Like

Thanks for the info. If so, I’m going to try a little on this side. I do have some ideas/inputs to test. And if I don’t manage, I will sure come back and ask css guru @RaananW to provide with his magic :mage:

2 Likes

Hello again,
I did some of my home work this morning looking at my resize/safari toolbar issue and looked for a fix using css, js or a manifest. Didn’t go through all of my attempts at this very moment: The moment I realized that you can get this exact same behavior straight from the PG. Any PG. The PG. On iOS/Safari, There is a blank space left under the canvas where the toolbar ‘auto-hides’ when you switch orientation from portrait to landscape. If you set Safari to go FS, there is no problem anymore.

To reproduce:

  • Open Safari on iOS
  • Open PG
  • Switch from portrait to landscape and you’ll see the blank space left from the hidden toolbar. If you go back to portrait, it will remain. If you click out of the scene (recall the toolbar) and then click/tap in the scene again, it will resize to fit.

So, I suppose question is: how can I instruct the scene/window to resize according to whether or not the faen toolbar is displayed? And then my second question would be, is there anything that can be done so that this behavior would not occur in the PG?

Thanks for your input if you have some… Meanwhile, I’m going to continue a little with my tests on device orientation detection and resizing.

Edit: Quickly did some more tests on more iOS/Safari with older type devices and got all sorts of different results. Tested ipad mini2 and 3. Tested iOS12.3.x, iPhone 5c. 13.4 on iPad. Tested iOS 14.4 iPhone6 (with a pending update).

  • Had no issue on iPads
  • The old iOS 12.x iPhone 5c displays an oversized BJS banner but the canvas resizes correctly.
    I will apply the pending update on the iPhone 6 and see if this removes the bug. (I had some experiences alike with Apple or also Windows, where a pending update would create some faen issue).

Edit 2: I have now applied latest 14.4.2 update on (what I believe to be an entry level device for 3D commerce), iPhone 6s device, but the issue remains.

I have this same exact issue, unfortunately I haven’t been able to find a working solution.

@RaananW might have a trick up his sleeve for this ???

Safari is the new IE, I am telling you…

I sadly (actually very happily) don’t have an iPhone to test with, but it does feel like a css-vs-babylon issue. If I understand correctly, portrait-landscape-portrait will have the canvas resize incorrectly. on canvas blur and then focus the canvas resizes correctly. Is everything displayed correctly then? does it only happen in the PG, or does every Babylon scene have the same issue on Safari?

What possible is that the engine resize code is executed before the CSS is applied to the container correctly, so it gets the wrong size, applies it, and only then does the canvas resize correctly. Try calling engine.resize() 50 ms after the device changed orientation. I wonder if it will solve the issue. It is, of course, not a proper solution, but will get us a step closer towards a solution :slight_smile:

1 Like

Try calling engine.resize() 50 ms after the device changed orientation.

I tried this to no avail – it just means that for that brief moment you see a squished/stretched render of the world, but still with the gap.

I’ve been hitting my head against this for a few days. I’m actually kind of relieved to see this thread, because that means it’s not just me messing up my CSS.

Looking at it with remote dev tools, the blank space is actually outside even the HTML element of the DOM. From my research (read: wanderings of random forum posts) it’s a general problem, not just a Babylon one. Even for simple layout with footers, it breaks the page. Some people had success listening for orientation change events and doing some trickery with scrolling, but those events don’t fire consistently, at least on the iOS 14 device I’m testing.

I keep thinking there’s gotta be a good CSS solution for it, but even the JavaScript based ones don’t seem to hold up, and I wouldn’t be as confident that they will continue to work into the future. Would love to hear other ideas…

I guess it’s out there but not too common. If it would be wide-spread apple would have been forced to solve this.
Might be the structure we are using for the playground. Something to do with ios’s html container system. Is that the issue? height:100% is not 100% after rota… | Apple Developer Forums
Have you tried using vh to define the container height? vh has its problems, but might be the solution for iOS

OK, after some more experimentation, I’ve found what I think is the best working solution for me. The beauty of it is that it’s actually quite simple, both the HTML and the CSS.

<html>
<body>
   <div class="scene">
      <canvas class="renderCanvas"></canvas>
   </div>
</body>
</html>
/* css */
html, body {
    margin: 0;
}

.scene {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}

.renderCanvas {
    width: 100%;
    height: 100%;
    touch-action: none;
}

This gives a rendering canvas that takes up the whole viewport, and continues to do so through rotations.

The one thing it does not handle is the initial load when the browser chrome is showing at the bottom of the screen. (The navigation/share/tabs buttons.) This little strip of buttons disappears after a rotation and back, but on initial load in portrait mode will be covering the bottom part of the viewport. Most of the workarounds that non-3D websites have gone through have centered around trying to either reclaim or rise above this space… I’m just electing to not render anything crucial down there and call it a day.

1 Like

Eh, it’s more common than you might think. Google “iOS viewport 100vh” and see the last several years of anguish as people keep trying different solutions that break on the next OS release. :unamused:

1 Like

We are talking Apple here yes? Based on 30 years working with Apple, I’d rather disagree with this part:( Apple does what is good for Apple. I will try the css trick and will also try top it up with a manifest.

1 Like

Anyone tried this on .html produced by Unity Babylon Exporter? It looks like it makes the issue x2 worse, if you wrap a canvas with .scene div.

@MackeyK24 might have ?

I have never tried chrome on my iphone

use ResizeObserver can solve

const resizeObserver = new ResizeObserver((entries) => {
            for (let i = 0; i < entries.length; i++) {
                engine.resize();
            }
        });
        resizeObserver.observe(this.canvasRef.current as Element);

Hi and Welcome to the Community,
I have to apologize here because I completely forgotten about this old topic and never marked it as solved. I havent’ tried your solution and I don’t have time right now but meanwhile other similar solutions have shown up (using the observer on resize like you suggest). Improvements have FINALLY been done in latest versions iOS to comply with WebGL methods and routines (thank you Apple, not as if it would have taken ages to conform to a standard :wink:
I will try find some time tomorrow to check out your method and if it works as expected, I will mark this as the solution.
Meanwhile, have a great sunday and again, welcome to the BJS Community. I hope you are enjoying the experience and have less troubles with mobile dev on iOS than we had couple of years ago :smiley:

1 Like

I used this solution to fix a similar problem…not sure why nesting in a div fixes it…but so be it.

1 Like

Thanks for sharing your experience with this. Have a great day :sunglasses:

The latest toolkit builds now support the nested canvas in a root div with 100vw and 100vh