preface

With the development of the company’s pay-for-knowledge business, products have found that landscape displays provide better results and experience than portrait displays. I also feel that is true ~. Just received this demand, a little thought, landscape screen this is not simple to directly rotate the whole page 90 degrees, is not finished? It turns out that the real development process is not so simple. For example, the direction of the gesture gesture slide over the screen has not changed and so on! So I tried to search baidu and finally did not find a satisfactory answer. Later decided to explore their own, the following is my development process summed up a set of practices, have a better student can also share corrections.

rendering

First, let me show you the renderings

Effect Picture 1:

It looks very tall ~, but this effect is for app native design, the actual H5 page in wechat inside access will also have the title bar and the bottom back bar, as shown in the following figure H5 actual display effect (Android) :

You can go in to experience the first (using WeChat access), project address m.ngmm365.com/mathbox/ind… After the page is loaded, click the study button to enter the landscape page.

Project requirements and analysis

The project requirements

1. Requirement 1: the planet in effect picture 1 should be able to support left and right sliding, and the sliding process should also be able to support 3D (near and far zoom) effect

2. Requirement 2: There will be multiple classes in effect picture 2 that can support left and right sliding

3, demand three: effect picture three content to just occupy a screen

Analysis of the

1. Analysis requirement 1: Swiper is used for planet switching.

2, analysis requirements two: it seems to be nothing difficult, using the system’s default scroll bar can support scrolling.

3, analysis needs three: mm ~, occupy a screen is not simple! Just go straight to the size of the renderings.

practice

The company uses the VUE technology stack, so the following components are written based on vUE. After understanding the principle, I believe that no matter what framework is used to implement it, there will be no big problem. Therefore, students who do not know vUE need not panic.

Problems and solutions

1. Now the first thing to do is how to make the page cross first?

Transform: Rotate (90deg) transform: rotate(90deg); So we need to have a landscape container component first. And then I’m going to put the contents of the corresponding page in this container so that the page is horizontal?

The landscape container component code is as follows:

<template> <section v-horizontal-screen @touchmove.prevent> <! - page specific content - > < slot > < / slot > < section > < / template > < script >export default {
	directives: {
        'horizontal-screen': {
            bind(el, binding, vnode){
                let self = vnode.context;
                
                function reset(init){
                    
                    letwidth = document.documentElement.clientWidth, height = document.documentElement.clientHeight; // In portrait state we add Transform: Rotate (90deg) to rotate the page horizontallyif(window. Orientation = = null | | window. The orientation "= = = 180 | | window. The orientation" = = = 0) {/ / vertical screen state el. Style. WebkitTransform =  el.style.transform = `rotate(90deg)`; el.style.width = `${height}px`;
                        el.style.height = `${width}px`;
                        el.style.webkitTransformOrigin = el.style.transformOrigin = `${width / 2}px center`; // If it is already in landscape state, do nothing else}else if(window. Orientation "= = = 90 | | window. The orientation" = = = - 90) {/ / landscape state el. Style. WebkitTransform = el. The style.css. Transform = `rotate(0)`; el.style.width = `${width}px`;
                        el.style.height = `${height}px`;
                    }
                }
                reset(true);

                let timer = null;
                el.fn = function(e) {
                    clearTimeout(timer);
                    timer = setTimeout(reset, 300);
                }
                
                window.addEventListener('resize', el.fn, false);

                if("onorientationchange" in window){
                    window.addEventListener('orientationchange', el.fn, false);
                }
            },
            unbind(el, binding, vnode){
                window.removeEventListener('resize', el.fn, false);
                window.removeEventListener('orientationchange', el.fn, false);
            }
        },
    }
}
</script>
Copy the code

Now that the page is horizontal, let’s start with a planet that can switch left and right. Can I just add swiper?

Try swiper, and when you run it, you’ll notice that the gesture is reversed, so that when you swipe up and down, the content slides left and right. Because now we’re just flipping the page, the X-axis and the Y-axis are the same. When we slide up and down, what we’re actually changing is the X-axis, which is the normal page slide left and right. With curiosity, I checked swiper’s API to see if there was any support for this operation parameter. The result did not find, had to try to modify the source code. Here is a screenshot of the revised code:

Added a parameter isReverse, which if true inverts the x and y axes. Of course, the isReverse has to be a special case where the app is already in landscape and there’s no need to flip the X and y axes. So we can slide our content along with our finger again.

In the previous tentative requirement two, the scrolling method adopts the default scroll bar to solve the problem. After the result is realized, the finger sliding direction is also found to be reverse. The original gesture is backwards, how do I adjust it? Checked on the net did not find an answer, the key this question is not very good description! Because iscroll has been used before, you can simulate the effect of the system scroll bar. Try to add it to the code, and find that the same swiper swiper can cause the finger to slide backwards. Finally, they can only go to the source code to add a parameter. Overall, iscroll changes much less code than Swiper. Just one change is needed. Here’s a screenshot:

With requirements one and two solved, we move on to the “simplest” third requirement. In fact, do not do any other operation in accordance with the idea, just need to write in accordance with the size of the renderings.

The page is written, and you can run it on the computer without any problems. I decided to deploy to the test environment and run it around on my phone. It turns out that the content on the right side is out of screen range. Because there are title bar and bottom bar in wechat, resulting in content beyond the scope of the screen. Think about the fact that on phones with different aspect ratios, the same thing would happen even if there were no title bar or bottom bar. How can this be solved? Finally, I decided to add an auto zoom component inside the landscape container component, and the frame of the final page looks like this. Of course the auto-scaling component is added only where it is needed.

<template>
	<div class="scale-wrap" :style="scaleWrapStyle">< slot></slot> </div> </template> <script> const DesignHeight = 667; const DesignRatio = DesignWidth / DesignHeight;function getScale() {let width = document.documentElement.clientWidth,
        height = document.documentElement.clientHeight;

    if(window. Orientation = = null | | window. The orientation "= = = 180 | | window. The orientation" = = = 0) {/ / vertical screen state}else {
    	[width, height] = [height, width];
    }

    let ratio = width / height;

    letscale; // Calculate the actual aspect ratio of the mobile phone and the effect of the aspect ratio to get the final ratioif(ratio > DesignRatio){
    	scale = height / (width / DesignRatio);
    }else if(ratio < DesignRatio){
    	scale = width / (height * DesignRatio);
    }else{
    	scale = 1;
    }

    return scale;

}

export default {
    data() {return {
        
        }
    },
    computed: {
        scaleWrapStyle() {let scale = getScale();
            let scaleStr = `scale(${scale}) `;return { 'transform': scaleStr, '-webkit-transform': scaleStr };
        }
    },
}
</script>
<style lang="less" scoped>
.scale-wrap{
	width: 100%;
	height:100%;
	display: flex;
	transform-origin: left center;
}
</style>
Copy the code

So far we have implemented a solution for dealing with landscape requirements

Of course, if you encounter landscape problems that cannot be solved by the previous solutions, you can also send them to discuss. See if there is a good way to solve the problem.

Finally, if the document helps you, give it a like

The relevant code

Github.com/taoxhsmile/…

A signature

by:Tao