小程序橫屏方案對比

前言

隨着小程序api開放的功能日漸增多,小程序能夠作到的功能和展示形式也愈來愈多,其中橫屏的展示形式就是其中的一種,而實現橫屏的方案也有多種,可是每種方案都有必定的缺陷,恰巧最近也在橫屏方案上踩了很多坑,接下來就來和你們分享一下小程序的不一樣橫屏方案的優劣(踩坑心得)css

組件自帶橫屏方法

小程序中的媒體組件通常都會提供全屏的方法,並且全屏方法中會提供一個direction的全屏參數,能夠經過這全屏參數將小程序旋轉90度橫屏展現,這是小程序中最簡單的橫屏方法。html

這個方法優勢在於調用的組件全屏方法作的橫屏,不須要考慮頭部導航欄的膠囊按鈕的顯示問題,媒體組件在作全屏顯示時,膠囊按鈕會自動隱藏不見,同時大多數媒體組件都已經支持了同層渲染,能夠經過z-index調整組件層級,所以用此法在橫屏佈局時能夠在媒體組件上覆蓋其餘組件佈局json

缺點:這個方法的缺點也很明顯,就是隻能使用媒體相關組件纔能有橫屏的全屏,場景很單一,若是不是媒體組件或者不想全屏,那麼對不起,此法不可用小程序

計算加速度判斷橫屏

這個方法是以前有人發在微信社區裏的一個方法,經過小程序提供的wx.onAccelerometerChange方法監聽設備在x、y、z軸上的加速度,經過返回的重力加速度計算設備的旋轉角度,下面貼出代碼給你們參考:api

// 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的回調,而且會在回調中返回當前是橫屏仍是豎屏以及相應區域的大小。spa

優勢:配置便可,手機旋轉觸發監聽事件,返回屏幕旋轉後的寬高和當前橫豎屏狀況,橫屏時膠囊按鈕會自動旋轉,這樣頁面佈局就不會有上一個方法所說起的怪異佈局設計

缺點:

  • 因爲是配置形式,沒辦法主動調用,只能被動監聽
  • 當用戶將手機容許旋轉關閉後,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建立步驟

總結

小程序中的橫屏方案老是有這樣或者那樣的問題,並無完美的解決方案,有時仍是小程序自身緣由致使的,咱們能作的只是尋找解決辦法或者換個交互設計,這篇文章的目的就是但願對你們在作橫屏方案時提供一點幫助,少踩坑,這是個人踩坑經歷,提供給你們借鑑,同時也有個人一些解決辦法,若是你們有更好的方案,能夠一塊兒學習。

若是有錯誤或不嚴謹的地方,歡迎批評指正,若是喜歡,歡迎點贊

相關文章
相關標籤/搜索