PlayCanvas HTML <canvas> is mispositioned after rotation on iOS Chrome

Hello,

I guess this is technically a bug report, but since I am not sure how much of it is because of the engine and how much of it is because of the editor tool chain, I’m posting it here.

I have a problem with the <canvas> element being positioned too high (not vertically centered anymore) after rotating the device in iOS Chrome when a) launching via the editor on launch.playcanvas.com and b) self-hosting. Everything works fine in every other browser I tried, including iOS Safari and Android Chrome. It also works fine in iOS Chrome if I don’t self-host, but instead use the playcanv.as as a host, everything is fine.

The problem is best shown in a video. You will see two elements:

  • The WebGL PlayCanvas canvas with the playing field and some PlayCanvas element text on it. As far as I remember, this is fully positioned by the original PlayCanvas CSS itself.
  • The HTML UI with the level title in the upper left, the pause button in the upper right and “Touch anywhere to continue.” at the bottom. This is positioned by CSS to be always centered, and scaled via “transform: scale()” by a PlayCanvas script which reacts to graphicsDevice.on('resizecanvas', ...).

On top of the mispositioned canvas, the the CSS transform-scaling doesn’t seem to trigger when rotating from Portrait to Landscape. Sadly I don’t have an iPad at the moment and can’t find out if resizecanvas just isn’t fired or if graphicsDevice reports the wrong width/height. Again: This is only the case in iOS Chrome.


First video: iOS Chrome, Portrait->Landscape->Portrait

  1. We start in Portrait mode, everything is fine. Notice how “Get out of Damascus” is above the playing field and a bit to the left.
  2. We rotate to Landscape mode. “Get out of Damascus” (and the whole HTML UI) is suddenly smaller. This is a second problem described; the transform scale didn’t update.
  3. We rotate back to Portrait mode. Suddenly the <canvas> is much higher.

Second video: iOS Chrome, Landscape->Portrait->Landscape

  1. We start in Landscape mode. This time, everything is fine. “Get Out of Damascus” is properly postioned and the HTML UI is well scaled, so my scaling seems to work in iOS Chrome Landscape too.
  2. We rotate to Portrait. Same as step #3 in the last video. (<canvas> too high.)
  3. We rotate back to Landscape. Same problem as step #2 in the last video. (HTML UI too small, scaling not updated or at all or not updated correctly.)

Third video: iOS Safari. Everything is fine here. Same in Android Chrome.


I can’t share my project, but here is a minimal example project showing the problem. (The buttons and Lorem Ipsum are UI, the grey bar is WebGL. The buttons should be on the left and right corner of the grey bar.)

It also depends on how it is launched/published:

So both problems only exist in iOS Chrome, and only when launching via editor or self-publishing.

I wish I could contribute more to finding out the why, but sadly I don’t have an iPad at the moment. Once I get my hands on one I’ll try to diagnose more. But in the meantime, maybe this bug report helps somebody else find the problem already.

Cheers,
Tobias

1 Like

Nobody? I assume it’s a bug since it a) works everywhere except in iOS Chrome and b) happens in editor and self-publishing, but not in playcanv.as publishing.)

Maybe you need to ping the core team. :laughing:
@dave @will @vaios @yaustar

1 Like

I finally got an iPad and I narrowed down what the problem with the UI scaling is: After rotating back to landscape, this.app.graphicsDevice.width/height are not refreshed and therefore reported wrong.

E.g.:

  1. Landscape: 1024x756
  2. Rotate…
  3. Portrait: 768x432
  4. Rotate…
  5. Landscape: 768x432

I have no idea why this happens in editor-launch/self-publishing, but not on playcanv.as-publishing (there, graphicsDevice.width/height refreshes correctly). I have no idea where the displacement comes from either. Sadly I don’t have a Mac and there is debug console on iOS Chrome, so my debugging capabilities are limited and I can’t inspect the DOM.

I’m also pretty bit disappointed that there’s no comment from @dave, @will, @vaios or @yaustar (or any other PlayCanvas developer) at all. I feel left alone here with what is clearly a PlayCanvas bug.

I have this issue before… And I solved it by setTimeout.

window.addEventListener('resize', function(e) {
    setTimeout(function() {
        app.resizeCanvas(width, height);
    }, 1000); // delay is important!!
});

As I found some related issues about orientation change on iOS:

I think that might be a different problem - the canvas is sized correctly, but graphicsDevice is reporting wrong width/heights despite displaying correctly.

(And since my UI is scaled by graphicsDevice width/height, it is too small after rotating.)

1 Like

Nobody? I assume it’s a bug since it a) works everywhere except in iOS Chrome and b) happens in editor and self-publishing, but not in playcanv.as publishing.)

The main different between the launcher in editor and the published page is an <iframe>.

The published page has an <iframe> which link to the main page of playcanvas application.

Maybe you can try it in you self-hosted page ?

<!doctype html>
<html>
<head>
    <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no' />
    <meta charset='utf-8'>
    <title>My Application</title>
    <style>
html, body {
    margin: 0;
    padding: 0;
    width: 100%;
    height: 100%;
}

#frame {
    border: none;
    width: 100%;
    height: 100%;
    overflow: hidden;
}
    </style>
</head>
<body>
    <iframe
        id="frame"
        src="./application.html"  <!-- link to your app index.html -->
        frameborder="0">
    </iframe>
</body>
</html>

I unfortunately don’t have an iDevice to test on and I don’t work for PlayCanvas.

The only note I can add is that the built projects run in an iFrame so can you try this https://playcanv.as/e/p/EgGnFGWQ/ (the extra e in the path makes this run without the iFrame) and see if you get the resizing bug?

Thank you both, @scarlex and @yaustar - the iframe was indeed the reason why it worked for playcan.as publishing! And as far as I tested, putting my self-hosted app into an iframe works around all the problems I’ve described here, including iOS Chrome.

Ah, sorry - I should’ve checked your profile before pinging you. All the more, thanks for your help.

1 Like

@TobiasW Congratulations !
In fact, I notice many issues about rotate device on iOS can be solved by an iframe. I think this is a bug on iOS safari, but I have no proof.

Thanks!

In this case, everything was fine in iOS Safari though, only iOS Chrome had the problem. Never saw any problems in iOS Safari, but then again, I’m not much of an iPad user.

1 Like