Detecting mobile device screen orientation when Responsive Layouts won't work

I have a Hype project that involves creating a stand alone html5 file that must be no larger than 5meg. There are several encoded base64 images and the file will be displayed on mobile devices (iOS, Android). I need a simple javascript that can detect the screen orientation of the mobile device and then advance the main timeline (in Hype) accordingly. Something like "if device is in landscape mode goto frame1, if portrait goto frame 2"... or something like that :wink: I assume I would put this script in the On Scene Load portion of my Hype project (at the beginning of my html file doc). Is anyone feeling generous for a newbie? I planned to use Responsive Layouts but they create html5 files that are too large for this exercise. Thanks in advance.

I'm not sure this is a good idea, especially if you're concerned about file size. I don't know exactly what you're doing, but if it was me, I'd probably just run the images through ImageOptim and just load them as normal files — unless I wanted to minimize server hits. That seems unlikely, unless it was a lot of little images. And in that scenario, and if I cared about too many server hits, I'd probably just use a sprite sheet.

https://www.w3schools.com/Css/css_image_sprites.asp

Meh, I'm feeling lazy. So, here's a start...

https://www.w3schools.com/jsref/prop_screen_width.asp

You can use the screen.width property to get the screen width. From there, it's trivial to detect landscape vs portrait.

if (screen.width > screen.height) {
     // landscape
} else {
     // portrait
}

...but remember the part when I said I was feeling lazy? I didn't feel like testing this on mobile. And since I wanted the page size — not the screen size — I used different properties...

 if (window.innerWidth > window.innerHeight) {
      console.log("Landscape")
 } else if (window.innerHeight > window.innerWidth) {
      console.log("Portrait")
 }

So, you can just load a scene instead of displaying a console message.

hypeDocument.showSceneNamed('sceneName', hypeDocument.kSceneTransitionCrossfade, 1.1) 

Easy... except... what if the website visitor changes the orientation of their browser? :scream_cat:

I don't know, I didn't feel like testing it... even though there's an iPhone to my left and an iPad to my right. :smirk:

...but I suspect this might help...

https://www.w3schools.com/jsref/event_onresize.asp

...I like using the onresize event because it works on desktop. I'm not sure if it works with what you're trying to do, but I suspect that it might help...

Some devices haven't provided the orientationchange event, but do fire the window's resize event

That's a pretty good article on the matter. It lists other ways to detect the orientation change. Me, I'm sleepy. :sleeping:

2 Likes

There is an easier solution. Just use layouts and assign the base64 images using the event HypeResourceLoad

I actually made an extension that does this already called Hype ImageBaseEncoder

This way base 64 images are stored in variables and can be reused across layouts.

You can also define the layout using the code from @Photics with the event HypeLayoutRequest to determine the layout to show.

sorry for the multiple reply/deletions. but thanks for the reply. hope you got some sleep. as you know, im trying to detect if the mobile device is landscape or portrait. hype does all the rest using something like this:

i'll try to emulate your ideas. again i am combining all assets into one stand alone html file... images, javascript, etc. i am so damn close but the publisher requires that i have a orientation script. they sent this...

window.addEventListener('orientationchange', (event) =>
{ console.log("orientation is now " + event.target.screen.orientation.angle);
});

when i ask the publisher for an example, they gave me a huge phaser code example that was impossible (for me) to dissect. i just need simple syntax! my code request seems like something that exists and would be common. anyway, i'll see if i can make yours work or your leads. thanks again.

thanks. responsive layouts are a terrific solution. but i am making a single stand alone html file. images, java, everything in one file. the problem with layouts is that they double the size of the stand alone html file i am trying to make. for example, if i make a landscape layout and a portrait layout, the stand alone html file is twice as large as if i made just one landscape version. hope that makes sense. i want to make a simple layout change using symbols and then tell hype which symbol to display (landscape or portrait) upon load using the java script i asked for help with.

I don't know why, I should be working on the Widgets app, but I looked into this problem. I turned it into a free template, which should launch Tuesday.

Yeah, that's right. You basically have the answer. Although, my example supports desktop and mobile.

While the template won't be available for a couple of days, here's the code now...

 window.HypeOrientation = "Landscape";
 window.resizingReady = false;

 if (!window.resizingReady) {
      window.addEventListener("resize", innerCheck);
      window.addEventListener("orientationchange", innerCheck);
      window.resizingReady = true;
 }

 function innerCheck() {
      if (window.innerWidth > window.innerHeight) {
           if (window.HypeOrientation != "Landscape") {
                hypeDocument.showSceneNamed("Landscape");
                window.HypeOrientation = "Landscape";
                console.log("Switched to " + window.HypeOrientation);
           }
      } else if (window.innerHeight > window.innerWidth) {
           if (window.HypeOrientation != "Portrait") {
                hypeDocument.showSceneNamed("Portrait");
                window.HypeOrientation = "Portrait";
                console.log("Switched to " + window.HypeOrientation);
           }
      }
      
      /*
      console.log("Width: " + window.innerWidth
           + " | Height: " + window.innerHeight
           + " | Orientation: " + window.HypeOrientation
           + " / " + window.orientation);
      */
 }

 innerCheck();

So what's going on? Well, I prefer to check the actual page size, rather than the screen size. Also, screen.orientation is... ehh... not strong enough right now.

...see how Safari (both on iOS and Desktop) is missing support? Meanwhile, window.orientation is deprecated...

That's why I don't even bother. I just look at the page size. If the width is larger, it's landscape. If the height is larger, it's portrait. Easy.

This is great because it works on desktop when the browser is not in full screen. But, since this needs to work in mobile too, I use an "orientationchange" event listener. The "resize" event listener alone was not enough to get the job done.

Also, you don't want to overdo it. That's why there's an extra set of conditionals. The "Landscape" scene is only loaded if the "Portrait" scene is current... and vice versa.

However, here's your problem...

If you're running a game, that's going to be weird. Changing scenes, based on orientation changes, can very likely cause the game to reset.

The solution to that problem is easy. Just rewrite everything in Phaser using Hype's Physics API. (Heh, I'm just kidding about that part.)

If you're focusing on iOS or Android, you could just limit the app to Landscape or Portrait. That's kinda lame, as 4-way auto-rotational support is a nice feature.

If you're trying to embed a Phaser game, that's where orientation detection should occur. At least, that's how I'd do it. The Hype piece should just be a box that changes size... a box that just expands / contracts to the available space.

1 Like

Ha! God forbid I have to work with that phaser example. This is a tremendous offering. Thanks for your time. This will be very useful for folks who use Scenes. Scenes like layouts are very useful. But the problem lies with the final output. Multiple scenes are like projects within a project. Each scene doubles the file size (in my single stand alone html file project). Much like using multiple Layouts. I believe I have to use one scene and one layout and move my menu around based on the orientation. Thats all I need to do. I might be able to use your code example to display certain symbols however. For example, I would have a symbol called "Landscape" and a symbol called "Portrait". Depending on the device orientation, I would reveal one symbol or the other. Or I could have certain timelines advance based on the orientation. Does that sound feasible?

I don’t see how your doubling output size. A scene or layout doesn’t add to the size significantly. If your talking about redundancy then this is another thing. That is something that increases. If your referencing images that is only a reference and shouldn’t really add much KB specially with a 5 Mb limit. If your using Base64 encoded images in self assigned innerHTML then you indeed double size but that can be avoided as mentioned. Just to clarify this for future reader. I’ll withdraw from this thread for now.

You'd think I'd never have posted a comment before. I figured it out. Thanks Photics for the fundamentals. I think this will work.

Photics provided the fundamentals which opened the door to hypeDocument.playTimelineNamed(... which opened the door to some other stuff. so far i think im in a good space. thanks to all. hope this thread helps other slow people. :wink:

1 Like

New template is online too...