前端 H5 横屏 独特处理方案详解

栏目: JavaScript · 发布时间: 6年前

内容简介:随着公司知识付费业务的发展,产品发现横屏展示内容的效果和体验都要比竖屏要来的好。我也感觉确实是这样的~。刚接到这个需求的时候,稍微想了一下,横屏这还不简单直接把整个页面旋转90度,不就完事了?结果真正开发的过程中发现并没有这么简单。比如屏幕横过来手势滑动的方向没有变过来等等!于是尝试去百度了一下最终并没有搜到满意的答案。后来决定自己摸索一下,下面是我开发过程中总结了一套做法,有更好的做好的同学也可以分享指正。效果图一:效果图二:

随着公司知识付费业务的发展,产品发现横屏展示内容的效果和体验都要比竖屏要来的好。我也感觉确实是这样的~。刚接到这个需求的时候,稍微想了一下,横屏这还不简单直接把整个页面旋转90度,不就完事了?结果真正开发的过程中发现并没有这么简单。比如屏幕横过来手势滑动的方向没有变过来等等!于是尝试去百度了一下最终并没有搜到满意的答案。后来决定自己摸索一下,下面是我开发过程中总结了一套做法,有更好的做好的同学也可以分享指正。

效果图

首先给大家看看效果图

效果图一:

前端 H5 横屏 独特处理方案详解

效果图二:

前端 H5 横屏 独特处理方案详解

效果图三:

前端 H5 横屏 独特处理方案详解

看上去还是挺高大上的吧~,不过这效果图是针对app原生设计的,实际H5页面在微信里面访问还会有标题栏和底部返回栏,如下图h5实际展示效果(android):

前端 H5 横屏 独特处理方案详解

大家可以进去先体验一下(用微信访问),项目地址 m.ngmm365.com/mathbox/ind… 页面加载完毕之后,点击试学按钮即可进入横屏页面。

项目需求及分析

项目需求

1、需求一:效果图一的星球要能支持左右滑动,滑动过程中还要能支持3D(远近缩放)的效果

2、需求二:效果图二会有多节课需要能支持左右滑动

3、需求三:效果图三内容要刚好占一屏

分析

1、分析需求一:星球切换部分使用swiper来实现。

2、分析需求二:好像没什么难的,使用系统默认的滚动条就可以支持滚动了。

3、分析需求三:嗯~,占一屏还不简单!直接按效果图尺寸写就好了。

实践总结

公司使用的是vue技术栈,所以下面的组件也是基于vue来写的。懂了原理我相信不管用什么框架去实现都不会有太大问题,所以不懂vue的同学也不用慌。

问题及解决方案

1、现在首先要做的第一件事情就是怎样先让页面横过来?

h5没有横屏属性那只能通过旋转页面的元素来达到横屏的效果了 transform: rotate(90deg); ,所以我们要首先要有一个 横屏容器 组件。然后把对应页面的内容都放在这个容器里面页面是不是就横过来了?

横屏容器组件代码如下:

<template>
    <section v-horizontal-screen @touchmove.prevent>
        <!-- 页面具体内容 -->
        <slot></slot>
    </section>
</template>
<script>
export default {
	directives: {
        'horizontal-screen': {
            bind(el, binding, vnode){
                let self = vnode.context;
                
                function reset(init){
                    
                    let width = document.documentElement.clientWidth,
                        height = document.documentElement.clientHeight;
                    //在竖屏状态我们通过添加transform:rotate(90deg),来让这个页面横过来
                    if(window.orientation == null || window.orientation === 180 || window.orientation === 0){//竖屏状态
                        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`;
                        //如果已经处于横屏状态就不做其他处理了
                    }else if(window.orientation === 90 || window.orientation === -90){//横屏状态
                        el.style.webkitTransform = el.style.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>
复制代码

现在页面已经横过来,接下来先让星球能够左右切换吧。是不是直接加入swiper插件就可以了?

尝试引入swiper插件,然后运行起来的时候会发现,手势反了,上下滑动的时候内容才会左右滑动。因为现在我们只是把页面横过来了,x轴和y轴并没有变。当我们上下滑动的时候实际上改变的是x轴,也就是正常页面的左右滑动。带着好奇心查了一下swiper的api看看是否有支持这种操作参数。结果没有查到,只好自己尝试去修改源码了。下面是修改代码后的部分截图:

前端 H5 横屏 独特处理方案详解

增加了一个参数isReverse,如果为true则x轴和y轴反一反。当然isReverse还要判断一下特殊情况比如本来app就已经横屏了其实就没必要x轴y轴互反了。这样我们的内容又可以正常跟着手指方向滑动了。

前面暂定需求二的滚动方式采用默认滚动条来解决,结果实现出来之后发现手指滑动方向也是反。原生的手势反了,改怎么调整呢?网上查了一通没有找到答案,关键这问题也不是很好描述!因为之前有使用过iscroll,可以模拟系统滚动条的效果。尝试加入到代码中,发现和swiper一样也会出现手指滑动方向反的情况。最后也只能自己去源码中增加一个参数了。整体对比iscroll改动的代码要比swiper少的多。只需要改一个地方就可以了,截图如下:

前端 H5 横屏 独特处理方案详解

需求一和需求二都解决了,接下来来解决“最简单”的第三个需求。其实按照设想不用做任何其它操作,只需要按照效果图的尺寸写就好了。

页面写好了,在电脑上跑也没什么问题。决定部署到测试环境用手机跑一下看看。结果发现右侧内容超出屏幕范围了。是因为在微信中有标题栏和底部栏,导致内容超出了屏幕范围。联想一下其实在不同长宽比的手机上 其实即使不存在标题栏和底部栏 其实也会有类似情况。这该怎么解决呢?最后决定在横屏容器组件内部再加入一个自动缩放组件,最后页面的框架图长下面这样。当然自动缩放组件只在需要的地方加入。

前端 H5 横屏 独特处理方案详解

接下来一起看看比例缩放容器的代码吧。

<template>
	<div class="scale-wrap" :style="scaleWrapStyle">

		<slot></slot>

	</div>
</template>
<script>
//这块宽高比例根据效果图来设置
const DesignWidth = 375;
const DesignHeight = 667;
const DesignRatio = DesignWidth / DesignHeight;

function getScale(){

    let width = document.documentElement.clientWidth,
        height = document.documentElement.clientHeight;

    if(window.orientation == null || window.orientation === 180 || window.orientation === 0){//竖屏状态
    	
    }else {
    	[width, height] = [height, width];
    }

    let ratio = width / height;

    let scale;

    //通过计算实际手机宽高比和效果图的宽高比得出最终的所让比例
    if(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>
复制代码

到此为止我们已经实现了对横屏需求处理的一套方案~


以上所述就是小编给大家介绍的《前端 H5 横屏 独特处理方案详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

失控的未来

失控的未来

[美]约翰·C·黑文斯 / 仝琳 / 中信出版集团 / 2017-4-1 / 59.00元

【编辑推荐】 20年前,尼古拉•尼葛洛庞帝的《数字化生存》描绘了数字科技给人们的工作、生活、教育和娱乐带来的冲击和各种值得思考的问题。数字化生存是一种社会生存状态,即以数字化形式显现的存在状态。20年后,本书以一种畅想的形式,展望了未来智能机器人与人类工作、生活紧密相联的场景。作者尤其对智能机器人与人类的关系,通过假设的场景进行了大胆有趣的描述,提出了人工智能的未来可能会面临的一些问题。黑文......一起来看看 《失控的未来》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

html转js在线工具
html转js在线工具

html转js在线工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具