How does the mobile terminal force the page landscape

ZuoPengFei 2017.12.13

1. The background

Recently, the company is going to develop a mobile terminal web-based game: long press the button and a bicycle will ride all the time. When it meets a national landmark, the corresponding “Hello” tip of that country will pop up, requiring horizontal display instead of vertical display.

However, when the user opens portrait, and does not turn on the landscape mode in the phone, the user must be forced to turn on. At this point, users will be impatient to shut down your game.

In addition, some apps on some phones cannot be landscape: for example, wechat on Android does not have landscape mode, while wechat on ios can enable landscape mode.

The solution is to write a landscape div in portrait mode and set rotate positive (negative) 90 degrees and rotate it around. If the user is in landscape mode, the rotate should be restored and displayed normally.

2. Pure CSS

Turn the main div sideways in portrait mode, unchanged in landscape.

@media screen and (orientation: portrait) { .main { -webkit-transform:rotate(-90deg); -moz-transform: rotate(-90deg); -ms-transform: rotate(-90deg); transform: rotate(-90deg); width: 100vh; height: 100vh; /* Overflow: hidden; /* Overflow: hidden; } } @media screen and (orientation: landscape) { .main { -webkit-transform:rotate(0); -moz-transform: rotate(0); -ms-transform: rotate(0); transform: rotate(0) } }Copy the code

The problem is that in landscape mode, the width and height are hard to control when rotated 90 degrees with CSS.

width: 100vh;
height: 100vh;

Copy the code

This does not work well on single-screen pages.

3. Js calculates width and height, alignment and rotation

As mentioned above, rotating to landscape width and height is problematic in Portrait. This can be done with the following js.

var width = document.documentElement.clientWidth;
var height =  document.documentElement.clientHeight;
if( width < height ){
  $print =  $('#print');
  $print.width(height);
  $print.height(width);
  $print.css('top',  (height-width)/2);
  $print.css('left',  0-(height-width)/2 );
  $print.css('transform' , 'rotate(90deg)');
  $print.css('transform-origin' , '50% 50%');
}

Copy the code

Note that transform-origin is 50% 50%. After rotating 90deg, you need to reset top and left to align them.

4. Final plan

If the user’s phone’s rotation button is on, the code still has a problem when the phone is turned sideways.

var evt = "onorientationchange" in window ? "orientationchange" : "resize";
      
    window.addEventListener(evt, function() {
        console.log(evt);
        var width = document.documentElement.clientWidth;
         var height =  document.documentElement.clientHeight;
          $print =  $('#print');
         if( width > height ){
           
            $print.width(width);
            $print.height(height);
            $print.css('top',  0 );
            $print.css('left',  0 );
            $print.css('transform' , 'none');
            $print.css('transform-origin' , '50% 50%');
         }
         else{
            $print.width(height);
            $print.height(width);
            $print.css('top',  (height-width)/2 );
            $print.css('left',  0-(height-width)/2 );
            $print.css('transform' , 'rotate(90deg)');
            $print.css('transform-origin' , '50% 50%');
         }
        
    }, false);

Copy the code

5. Complete code

/ * * * * @ somehow screen param {Object} * / function changeOrientation ($print) {var width = document. DocumentElement. ClientWidth; var height = document.documentElement.clientHeight; if(width < height) { $print.width(height); $print.height(width); $print.css('top', (height - width) / 2 ); $print.css('left', 0 - (height - width) / 2 ); $print.css('transform', 'rotate(90deg)'); $print.css('transform-origin', '50% 50%'); } var evt = "onorientationchange" in window ? "orientationchange" : "resize"; window.addEventListener(evt, function() { setTimeout(function() { var width = document.documentElement.clientWidth; var height = document.documentElement.clientHeight; // Refresh the city width initCityWidth(); CityCrashDistanceArr = initCityCrashDistance(); if( width > height ){ $print.width(width); $print.height(height); $print.css('top', 0 ); $print.css('left', 0 ); $print.css('transform' , 'none'); $print.css('transform-origin' , '50% 50%'); } else { $print.width(height); $print.height(width); $print.css('top', (height-width)/2 ); $print.css('left', 0-(height-width)/2 ); $print.css('transform' , 'rotate(90deg)'); $print.css('transform-origin' , '50% 50%'); }}, 300); }, false); }Copy the code

6. Summary

  • This scheme is only suitable for page width and height of a screen, not suitable for the scheme can scroll
  • Using orientationchange and resize to monitor horizontal and vertical screen switching will cause delays. For specific solutions, please refer to my other article js implementation of mobile phone horizontal and vertical screen events

7. Reference materials

  • How to make the mobile page forced landscape

8. demo

Code 9.

code