小程序横屏方案对比

前言

随着小程序api开放的功能日渐增多,小程序可以做到的功能和展现形式也越来越多,其中横屏的展现形式就是其中的一种,而实现横屏的方案也有多种,但是每种方案都有一定的缺陷,恰巧最近也在横屏方案上踩了不少坑,接下来就来和大家分享一下小程序的不同横屏方案的优劣(踩坑心得)

组件自带横屏方法

小程序中的媒体组件一般都会提供全屏的方法,而且全屏方法中会提供一个direction的全屏参数,可以通过这全屏参数将小程序旋转90度横屏展示,这是小程序中最简单的横屏方法。

这个方法优点在于调用的组件全屏方法做的横屏,不需要考虑头部导航栏的胶囊按钮的显示问题,媒体组件在做全屏显示时,胶囊按钮会自动隐藏不见,同时大多数媒体组件都已经支持了同层渲染,可以通过z-index调整组件层级,因此用此法在横屏布局时可以在媒体组件上覆盖其他组件布局

缺点:这个方法的缺点也很明显,就是只能使用媒体相关组件才能有横屏的全屏,场景很单一,如果不是媒体组件或者不想全屏,那么对不起,此法不可用

计算加速度判断横屏

这个方法是之前有人发在微信社区里的一个方法,通过小程序提供的wx.onAccelerometerChange方法监听设备在x、y、z轴上的加速度,通过返回的重力加速度计算设备的旋转角度,下面贴出代码给大家参考:

// 0为竖屏,1为横屏
  let lastState = 0;
  let lastTime = Date.now();

  wx.startAccelerometer();

  wx.onAccelerometerChange((res) => {
    const now = Date.now();

    // 500ms检测一次
    if (now - lastTime < 500) {
      return;
    }
    lastTime = now;

    let nowState;

    // 57.3 = 180 / Math.PI
    const Roll = Math.atan2(-res.x, Math.sqrt(res.y * res.y + res.z * res.z)) * 57.3;
    const Pitch = Math.atan2(res.y, res.z) * 57.3;

    // console.log('Roll: ' + Roll, 'Pitch: ' + Pitch)

    // 横屏状态
    if (Roll > 50) {
      if ((Pitch > -180 && Pitch < -60) || (Pitch > 130)) {
        nowState = 1;
      }else {
        nowState = lastState;
      }

    }else if ((Roll > 0 && Roll < 30) || (Roll < 0 && Roll > -30)) {
      let absPitch = Math.abs(Pitch);

      // 如果手机平躺,保持原状态不变,40容错率
      if ((absPitch > 140 || absPitch < 40)) {
        nowState = lastState;
      }else if (Pitch < 0) {/*收集竖向正立的情况*/
        nowState = 0;
      }else {
        nowState = lastState;
      }
    }
    else {
      nowState = lastState;
    }

    // 状态变化时,触发
    if (nowState !== lastState) {
      lastState = nowState;
      if (nowState === 1) {
        console.log('change:横屏');
      }else {
        console.log('change:竖屏');
      }
    }
  });
  • 优点:这个方法的优点在于可以监听到设备的横竖屏情况,然后根据项目需要展示不同横竖屏布局,自由度很高

  • 缺点:这个方法的缺点在于在页面内容横屏时无法使头部导航栏的胶囊按钮横屏展示,因为头部导航栏的胶囊按钮始终是固定屏幕右上角不动的,这样会使得横屏效果有点奇怪,横屏是导航栏固定在左边是竖屏时的布局,除非横屏的布局是媒体组件的全屏,这样就能遮住胶囊按钮,自己自定义一个头部导航,这样就不会显得布局奇怪

pageOrientation

pageOrientation是小程序提供的配置属性,可以设置当前页面是横屏展示、竖屏展示、或者自动旋转,同时提供一个onResize的监听方法,当屏幕发生旋转时会触发onResize的回调,并且会在回调中返回当前是横屏还是竖屏以及相应区域的大小。

  • 优点:配置即可,手机旋转触发监听事件,返回屏幕旋转后的宽高和当前横竖屏情况,横屏时胶囊按钮会自动旋转,这样页面布局就不会有上一个方法所提及的怪异布局

  • 缺点:

    • 由于是配置形式,没办法主动调用,只能被动监听
    • 当用户将手机允许旋转关闭后,onResize的监听方法就不会触发
    • 由于小程序大多数时候使用的是rpx的单位,是一个基于响应区域大小的动态计算的单位,当屏幕发生旋转后,假设竖屏旋转到横屏,竖屏时响应区域为375 *667,到了横屏时响应区域为667 *375,此时onResize回调还没触发,此时的页面布局是竖屏的布局,但是由于响应区域发生变化375 *667到667 *375,rpx就会重新计算,此时页面的布局会突然变大,然后onResize回调触发后才会变为横屏布局,会有布局闪现错乱的情况
    • width:100%或者width:100vw这类的占满全部的样式也会出现问题,同样假设从竖屏切换到横屏,当竖屏切换的横屏时,此时width:100%的样式,计算100%的宽度还是竖屏时的375,不会立即切换到横屏时的667,因此切换到横屏时的一瞬间,能看到原来100%的样式,此时并没有占满100%,闪了一下375之后,然后才会占满,假设我们自定义的顶部标题栏,用了width:100%,那么我横屏时就会发现,标题栏宽度只有一半,然后才会占满

横屏时响应区域变化产生布局变化的解决办法

这个解决办法只能解决横屏时由于响应区域变化导致rpx重新的计算渲染的问题,既然rpx会在响应区域变化时重新计算渲染,那我们最直接粗暴简单的方法就是不使用动态计算的单位px,这样就不会在横屏时重新渲染计算,但是这样也有一个问题,就是在不同屏幕的大小的手机下也没法动态计算了

那有没有其他的更好办法呢?vmax、vmin这两个单位应该平时用的不多,个人也很少用,如果不是这次写小程序横屏,也不会关注到它

vmin:取值是当前vw和vh中较小的值,vmax:取值是当前vw和vh中较大的值

在竖屏时100vmin=375px,到了横屏时100vmin=375px,这样就能保证在横竖屏切换的时候内容大小不变,在小程序中使用calc(vmin/7.5),假设大小为10px,那么css为calc(10vmin/7.5),如果你嫌这么写麻烦,同时使用的是vs code,那么可以创建一个全局User Snippets:

"rpx to vmin" : {
  "prefix": "tovmin",
  "body": ["calc($0vmin / 7.5)"],
  "description": "rpx to vmin"
 }

这样在写css时直接写tomin就会将calc($0vmin / 7.5)输出


官方snippets创建步骤

总结

小程序中的横屏方案总是有这样或者那样的问题,并没有完美的解决方案,有时还是小程序自身原因导致的,我们能做的只是寻找解决办法或者换个交互设计,这篇文章的目的就是希望对大家在做横屏方案时提供一点帮助,少踩坑,这是我的踩坑经历,提供给大家借鉴,同时也有我的一些解决办法,如果大家有更好的方案,可以一起学习。

原文:https://segmentfault.com/a/1190000023025429

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354