簡單地描述一下區別,後面會更詳細對比:
DeviceOrientationEvent是擷取方向,得到device靜止時的絕對值;
DeviceMotionEvent是擷取移動速度,得到device移動時相對之前某個時間的差值比。
--------------------------------------------------------------------------------
背景知識:
Apple官方依然只發現一個文檔:
還是沒例子的,自己寫:
[html]
<html>
<head>
<title>DeviceMotionEvent</title>
<meta charset="UTF-8" />
</head>
<body>
<p>x軸加速度:<span id="x">0</span>米每二次方秒</p>
<p>y軸加速度:<span id="y">0</span>米每二次方秒</p>
<p>z軸加速度:<span id="z">0</span>米每二次方秒</p>
<hr />
<p>x軸加速度(考慮重力加速度):<span id="xg">0</span>米每二次方秒</p>
<p>y軸加速度(考慮重力加速度):<span id="yg">0</span>米每二次方秒</p>
<p>z軸加速度(考慮重力加速度):<span id="zg">0</span>米每二次方秒</p>
<hr />
<p>左右旋轉速度:<span id="alpha">0</span>度每秒</p>
<p>前後旋轉速度:<span id="beta">0</span>度每秒</p>
<p>扭轉速度:<span id="gamma">0</span>度每秒</p>
<hr />
<p>上次收到通知的間隔:<span id="interval">0</span>毫秒</p>
<script type="text/javascript">
function motionHandler(event) {
document.getElementById("interval").innerHTML = event.interval;
var acc = event.acceleration;
document.getElementById("x").innerHTML = acc.x;
document.getElementById("y").innerHTML = acc.y;
document.getElementById("z").innerHTML = acc.z;
var accGravity = event.accelerationIncludingGravity;
document.getElementById("xg").innerHTML = accGravity.x;
document.getElementById("yg").innerHTML = accGravity.y;
document.getElementById("zg").innerHTML = accGravity.z;
var rotationRate = event.rotationRate;
document.getElementById("alpha").innerHTML = rotationRate.alpha;
document.getElementById("beta").innerHTML = rotationRate.beta;
document.getElementById("gamma").innerHTML = rotationRate.gamma;
}
if (window.DeviceMotionEvent) {
window.addEventListener("devicemotion", motionHandler, false);
} else {
document.body.innerHTML = "What user agent u r using???";
}
</script>
</body>
</html>
<html>
<head>
<title>DeviceMotionEvent</title>
<meta charset="UTF-8" />
</head>
<body>
<p>x軸加速度:<span id="x">0</span>米每二次方秒</p>
<p>y軸加速度:<span id="y">0</span>米每二次方秒</p>
<p>z軸加速度:<span id="z">0</span>米每二次方秒</p>
<hr />
<p>x軸加速度(考慮重力加速度):<span id="xg">0</span>米每二次方秒</p>
<p>y軸加速度(考慮重力加速度):<span id="yg">0</span>米每二次方秒</p>
<p>z軸加速度(考慮重力加速度):<span id="zg">0</span>米每二次方秒</p>
<hr />
<p>左右旋轉速度:<span id="alpha">0</span>度每秒</p>
<p>前後旋轉速度:<span id="beta">0</span>度每秒</p>
<p>扭轉速度:<span id="gamma">0</span>度每秒</p>
<hr />
<p>上次收到通知的間隔:<span id="interval">0</span>毫秒</p>
<script type="text/javascript">
function motionHandler(event) {
document.getElementById("interval").innerHTML = event.interval;
var acc = event.acceleration;
document.getElementById("x").innerHTML = acc.x;
document.getElementById("y").innerHTML = acc.y;
document.getElementById("z").innerHTML = acc.z;
var accGravity = event.accelerationIncludingGravity;
document.getElementById("xg").innerHTML = accGravity.x;
document.getElementById("yg").innerHTML = accGravity.y;
document.getElementById("zg").innerHTML = accGravity.z;
var rotationRate = event.rotationRate;
document.getElementById("alpha").innerHTML = rotationRate.alpha;
document.getElementById("beta").innerHTML = rotationRate.beta;
document.getElementById("gamma").innerHTML = rotationRate.gamma;
}
if (window.DeviceMotionEvent) {
window.addEventListener("devicemotion", motionHandler, false);
} else {
document.body.innerHTML = "What user agent u r using???";
}
</script>
</body>
</html>用MobileSafari或UIWebView開啟以上網頁,可以看到10個數值的即時變化。
(其中左圖是把ipad平放在水平桌子上時的數值,右圖是快速轉動ipad時的數值。從右圖可看到,因為表示的是速度,單位是度每秒,所以絕對值可以大於360。)
(點擊圖片看大圖)
這十個屬性分別是:
event.acceleration.x(y,z):x(y,z)軸方向上,裝置移動的加速度。請看《iOS Safari/WebKit對DeviceOrientationEvent的實現》中的圖示。
event.accelerationIncludingGravity.x(y,z):考慮重力加速度後x(y,z)軸方向上的加速度。因為重力加速度隻影響z軸,所以與acceleration的數值相比,x軸和y軸是一樣的,z軸相差9.8左右。(絕對數值不相等是因為浮點數精度問題)
旋轉速度rotationRate:alpha、beta、gamma的概念與DeviceOrientationEvent一致。區別在於:DeviceOrientationEvent的值是相對於初始狀態的差值,只要裝置方向不變,怎麼動都不會影響數值;DeviceMotionEvent是相對於之前的某個瞬間值的差值時間比,即變化的速度,一旦裝置靜止則會恢複為0。
event.interval是 距離上次收到回調通知的時間間隔。
--------------------------------------------------------------------------------
相關類的關係圖:
和DeviceOrientationEvent的非常類似,只不過因為資料個數太多,用了DeviceMotionData來做資料容器。
執行JavaScript遇到addEventListener時的瀏覽器堆棧是幾乎一樣的。在回調通知的區別也就僅在傳的參數多了幾個。
[plain]
Thread 5 WebThread, Queue : (null)
#0 0x387bec96 in WebCore::EventTarget::dispatchEvent(WTF::PassRefPtr<WebCore::Event>) ()
#1 0x389a8a50 in WebCore::DeviceMotionController::didChangeDeviceMotion(WebCore::DeviceMotionData*) ()
#2 0x389a83cc in WebCore::DeviceMotionClientIOS::motionChanged(double, double, double, double, double, double, double, double, double) ()
#3 0x38974b0a in __48-[CoreMotionManager sendMotionData:withHeading:]_block_invoke_0 ()
Thread 5 WebThread, Queue : (null)
#0 0x387bec96 in WebCore::EventTarget::dispatchEvent(WTF::PassRefPtr<WebCore::Event>) ()
#1 0x389a8a50 in WebCore::DeviceMotionController::didChangeDeviceMotion(WebCore::DeviceMotionData*) ()
#2 0x389a83cc in WebCore::DeviceMotionClientIOS::motionChanged(double, double, double, double, double, double, double, double, double) ()
#3 0x38974b0a in __48-[CoreMotionManager sendMotionData:withHeading:]_block_invoke_0 ()
--------------------------------------------------------------------------------
PS:
1. Mac WebKit的類還留在iOS版裡冗餘著,根本沒用,例如WebDeviceOrientation。
2. 需要真機調試,模擬器不支援Core Motion。