移動端中的陀螺儀

小火柴的藍色理想發表於2018-03-06

前面的話

  本文將詳細介紹移動端中的陀螺儀的概念及相關實現

 

橫豎屏

  window下的orientation屬性來表示移動端的橫豎屏狀態,chrome模擬器不支援該屬性,只能在真機上測試

window.orientation

  按照上右下左的順序,該屬性的結果分別是0、90、180、-90

  [注意]手機頭朝下的切換沒有實現

  window下的orientationchange事件來監測移動端的橫豎屏狀態

  [注意]橫豎屏切換也會觸發resize事件

    window.addEventListener('orientationchange',()=>{
      alert(window.orientation)
    })

  測試程式碼如下

<style>
#box{
  width: 100px;
 height: 100px; line
-height: 100px; background: pink; margin: 30px auto 0; text-align: center; } </style> <div id="box"></div> <script> let oBox = document.getElementById('box') window.addEventListener('orientationchange',()=>{ oBox.innerHTML = window.orientation }) </script>

  檢視效果

 

裝置方向

  deviceorientation事件用來監聽裝置的方向

  裝置在三維空間中是靠x、y和z軸來定位的。當裝置靜止放在水平表面上時,這三個值都是0

  x軸方向是從左往右,y軸方向是從下往上,z軸方向是從後往前

  觸發deviceorientation事件時,事件物件中包含著每個軸相對於裝置靜止狀態下發生變化的資訊,事件物件包含以下5個屬性

alpha:在圍繞z軸旋轉時(即左右旋轉時),y軸的度數差;是一個介於0到360之間的浮點數
beta:在圍繞x軸旋轉時(即前後旋轉時),z軸的度數差;是一個介於-180到180之間的浮點數
gamma:在圍繞y軸旋轉時(即扭轉裝置時),z軸的度數差;是一個介於-90到90之間的浮點數
absolute:布林值,表示裝置是否返回—個絕對值
compassCalibrated:布林值,表示裝置的指南針是否校準過

  手機放置在水平桌面上,android的alpha、beta、gamma值為90、0、0;IOS的alpha、beta、gamma值為0、0、0

  測試程式碼如下

<style>
#box{
  width: 100px;
  line-height: 100px;
  height: 100px;
  background: pink;
  margin: 30px auto 0;
  text-align: center;
}  
</style>
<div id="box"></div>
<script>
let oBox = document.getElementById('box');
window.addEventListener('deviceorientation',(e)=>{
  oBox.innerHTML = Math.round(e.beta)
  oBox.style.transform = `rotate(${e.beta}deg)`
})
</script>

  檢視效果

 

裝置移動

  window.devicemotion事件告訴開發人員裝置什麼時候移動,而不僅僅是裝置方向如何改變

  要特別注意的是,移動端chrome65有一個bug,devicemotion和deviceorientation事件只能監聽一個

  觸發devicemotion事件時,事件物件包含以下屬性

acceleration:一個包含X、y和z屬性的物件,在不考慮重力的情況下,告訴你在每個方向上的加速度
accelerationIncludingGravity: 一個包含x、y和z屬性的物件,在考慮z軸自然重力加速度的情況下,告訴你在每個方向上的加速度
interval:以毫秒錶示的時間值,必須在另一個devicemotion事件觸發前傳入。這個值在每個事件中應該是一個常量
rotationRate: —個包含表示方向的alpha、beta和gamma屬性的物件

  手機在不同方向下,android和IOS的acceleration和accelerationlncludingGravity這兩個屬性的x、y、z的值表示不同

  1、放置在水平桌面上

android x:0 y:0 z:10
IOS x:0 y:0 z:-10

  2、螢幕朝右

android x:-10 y:0 z:0
IOS x:10 y:0 z:0

  3、螢幕正對人

android x:0 y:10 z:0
IOS x:0 y:-10 z:0

  所以,android和IOS下重力加速度的取值相反

【元素跟隨手機移動】

  下面利用accelerationlncludingGravity屬性實現元素跟隨手機移動的效果

  測試程式碼如下

<style>
#box{
  width: 100px;
  height: 100px;
  background: pink;
  margin: 30px auto 0;
  text-align: center;
}  
</style>
<div id="box"></div>
<script>
let oBox = document.getElementById('box');
let lastX=0,lastY=0,lastZ=0;
window.addEventListener('devicemotion',(e)=>{
  requestAnimationFrame(()=>{
    let {x,y,z} = e.accelerationIncludingGravity
    x = 6*x
    y = 6*y
    z = 6*z
    oBox.style.transform = `translate3d(${x+lastX}px,${y+lastY}px,${z+lastZ}px)`
    lastX = x
    lastY = y
    lastZ = z    
  })
})
</script>

  檢視效果

【搖一搖】

  搖一搖的原理非常簡單,檢測到手機的重力加速忽然有比較大的變化幅度即可。搖一搖時,元素顏色發生變化

  測試程式碼如下

<style>
#box{
  width: 100px;
  height: 100px;
  background: pink;
  margin: 30px auto 0;
  text-align: center;
  transition: 1s;
}  
</style>
<div id="box"></div>
<script>
let oBox = document.getElementById('box');
let colorArr = ['orange','lightblue','lightgreen','pink','lightyellow']
let lastX,lastY,lastZ
let index = 0
window.addEventListener('devicemotion',(e)=>{
  requestAnimationFrame(()=>{
    let {x,y,z} = e.accelerationIncludingGravity
    let nowRange = Math.abs(lastX -x) + Math.abs(lastY - y) + Math.abs(lastZ - z) 
    if(nowRange > 80){
      index = (index+1)%colorArr.length
      oBox.style.background = colorArr[index]
    }
    lastX = x 
    lastY = y
    lastZ = z 
  })
})
</script>

  檢視效果

 

相關文章