您當前位置>首頁 » 新聞資(zī)訊 » 小程序相關(guān) >
小程序基于加速度計判斷橫豎屏
發表時間:2021-3-26
發布人:葵宇科技
浏覽次數:55
也許有人會問(wèn),小程序中(zhōng)都是豎直app形态,要橫豎屏判斷有什麼用?即使判斷出了橫屏狀态,你(nǐ)能把小程序橫過來?答案是不能的,但是判斷當前設備處于橫屏或者豎屏狀态來實現一些友好的用戶體驗交互方式的需求确實存在。例如(rú)手機橫屏,讓視頻播放自動(dòng)全屏,手機豎屏,讓視頻切換回來小屏。
然而,截止至目前,小程序官方的API中(zhōng)并沒有提供這樣的橫豎屏判斷的方法。那麼我們隻能自己想辦法實現這樣的判斷。小程序的設備API中(zhōng)提供了加速度計的監聽方法,使用方法如(rú)下(xià):
wx.onAccelerometerChange(function(res) {
console.log(res.x)
console.log(res.y)
console.log(res.z)
})
加速度計的三軸
以下(xià)是一般移動(dòng)設備的加速度計三軸坐(zuò)标系示例圖:
以手機豎直面向用戶為例,加速計的三軸坐(zuò)标系統的X、Y、Z軸定義如(rú)下(xià):
- 沿着手機屏幕頂部向上是Y軸正方向,向下(xià)是Y軸負方向;
- 當手機頂部朝上時,沿着手機屏幕向右是X軸正方向,向左是X軸負方向;
- 正對手機時,垂直屏幕向外是Z軸正方向,垂直屏幕向裡是Z軸負方向;
當手機處于靜止狀态時,手機此時隻受一個(gè)重力加速度(1g=9.8m/s2)的作用,加速度計返回的res.x、res.y、res.z的值就是設備的三軸受到的加速度的值,取值範圍從[-1g,1g]。設備以不同方式放置時,x/y/z的值如(rú)下(xià):
計算姿态角
在stackoverflow上找到了根據加速度計三軸的值計算姿态角公式(https://stackoverflow.com/questions/3755059/3d-accelerometer-calculate-the-orientation),經過結合設備的三軸坐(zuò)标方向對公式進行調整,最終得出了公式:
Pitch
=
atan2(Y,
Z)
*
180/M_PI;Roll
=
atan2(-X,
sqrt(Y*Y
+
Z*Z))
*
180/M_PI;
Roll
=
atan2(-X,
sqrt(Y*Y
+
Z*Z))
*
180/M_PI;
- Roll(繞Y軸旋轉的角度)
當設備繞着自身Y軸旋轉時(表示手機左側或右側翹起的角度),該角度值将會發生變化,取值範圍是-90到90度。
- Pitch(繞X軸旋轉的角度)
當手機繞着自身的Y軸旋轉(表示手機頂部或尾部翹起的角度),該角度會發生變化,值的範圍是-180到180度。
接下(xià)來就是根據自己對橫豎屏角度的觀測,再結合微信小程序中(zhōng),視頻全屏隻能以手機向左旋轉方式全屏的特性,隻對用戶左側橫屏判斷為橫屏狀态,實現代碼片段如(rú)下(xià):
// 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);
// 如(rú)果手機平躺,保持原狀态不變,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:豎屏');
}
}
});
然後就可(kě)以在橫豎屏切換的狀态下(xià),去切換視頻的橫豎屏了
if (state === 1) {
video.requestFullScreen();
} else {
video.exitFullScreen();
}
其他
另外,在這裡發現小程序的一個(gè)小bug,就是當進入一個(gè)頁面,馬上就調用requestFullScreen()方法去拉起視頻全屏時,會破壞整個(gè)頁面的布局,并且再調用全屏方法時,視頻就無法再全屏了,像這樣:
所以為了防止用戶直接以橫屏的狀态進入一個(gè)視頻播放頁,而我們的橫屏判斷檢測生效立即觸發全屏引發bug,我将監聽橫豎屏的事件通(tōng)過setTimeout(listener, 3000)延遲3s監聽,這樣橫屏才不會觸發bug。
最後
文(wén)中(zhōng)的很多知識點很多都是從網絡文(wén)章學來,可(kě)能存在錯誤的理解,如(rú)有錯誤,歡迎各位指正。
最後再打個(gè)廣告,歡迎喜歡看遊戲直播的小夥伴來試用我們的《TG電競》直播小程序,這裡聚合各大平台的知名主播,總有一款适合你(nǐ)哦。
本文(wén)作者:志安_Chen
原文(wén)地址:基于加速度計判斷橫豎屏 | 微信公衆平台 開發者社區