1. 程式人生 > 程式設計 >詳解小程式橫屏方案對比

詳解小程式橫屏方案對比

前言

隨著小程式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建立步驟

總結

小程式中的橫屏方案總是有這樣或者那樣的問題,並沒有完美的解決方案,有時還是小程式自身原因導致的,我們能做的只是尋找解決辦法或者換個互動設計,這篇文章的目的就是希望對大家在做橫屏方案時提供一點幫助,少踩坑,這是我的踩坑經歷,提供給大家借鑑,同時也有我的一些解決辦法,如果大家有更好的方案,可以一起學習。

到此這篇關於詳解小程式橫屏方案對比的文章就介紹到這了,更多相關小程式橫屏內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!