iOS Safari/WebKit对DeviceMotionEvent的实现

本文深入解析了iOS Safari/WebKit中用于获取设备方向和移动速度的两个事件:DeviceOrientationEvent和DeviceMotionEvent。通过实际代码示例,展示了如何在网页中实时获取并显示设备的加速度、加速度(考虑重力)、旋转速度以及通知间隔等数据,以及这两个事件的主要区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请先阅读《iOS Safari/WebKit对DeviceOrientationEvent的实现》,本文是姐妹篇。

简单地描述一下区别,后面会更详细对比:

DeviceOrientationEvent是获取方向,得到device静止时的绝对值;
DeviceMotionEvent是获取移动速度,得到device移动时相对之前某个时间的差值比。


背景知识:

Apple官方依然只发现一个文档:

https://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/DeviceMotionEventClassRef/DeviceMotionEvent/DeviceMotionEvent.html

还是没例子的,自己写:https://code.youkuaiyun.com/hursing/pagetest/blob/master/devicemotionevent.html

  1. <html>  
  2.     <head>  
  3.        <title>DeviceMotionEvent</title>  
  4.        <meta charset="UTF-8" />  
  5.     </head>  
  6.     <body>  
  7.         <p>x轴加速度:<span id="x">0</span>米每二次方秒</p>  
  8.         <p>y轴加速度:<span id="y">0</span>米每二次方秒</p>  
  9.         <p>z轴加速度:<span id="z">0</span>米每二次方秒</p>  
  10.         <hr />  
  11.         <p>x轴加速度(考虑重力加速度):<span id="xg">0</span>米每二次方秒</p>  
  12.         <p>y轴加速度(考虑重力加速度):<span id="yg">0</span>米每二次方秒</p>  
  13.         <p>z轴加速度(考虑重力加速度):<span id="zg">0</span>米每二次方秒</p>  
  14.         <hr />  
  15.         <p>左右旋转速度:<span id="alpha">0</span>度每秒</p>  
  16.         <p>前后旋转速度:<span id="beta">0</span>度每秒</p>  
  17.         <p>扭转速度:<span id="gamma">0</span>度每秒</p>  
  18.         <hr />  
  19.         <p>上次收到通知的间隔:<span id="interval">0</span>毫秒</p>  
  20.         <script type="text/javascript">  
  21.         function motionHandler(event) {  
  22.             document.getElementById("interval").innerHTML = event.interval;  
  23.             var acc = event.acceleration;  
  24.             document.getElementById("x").innerHTML = acc.x;  
  25.             document.getElementById("y").innerHTML = acc.y;  
  26.             document.getElementById("z").innerHTML = acc.z;  
  27.             var accGravity = event.accelerationIncludingGravity;  
  28.             document.getElementById("xg").innerHTML = accGravity.x;  
  29.             document.getElementById("yg").innerHTML = accGravity.y;  
  30.             document.getElementById("zg").innerHTML = accGravity.z;  
  31.             var rotationRate = event.rotationRate;  
  32.             document.getElementById("alpha").innerHTML = rotationRate.alpha;  
  33.             document.getElementById("beta").innerHTML = rotationRate.beta;  
  34.             document.getElementById("gamma").innerHTML = rotationRate.gamma;  
  35.         }  
  36.           
  37.         if (window.DeviceMotionEvent) {  
  38.           window.addEventListener("devicemotion", motionHandler, false);  
  39.         } else {  
  40.           document.body.innerHTML = "What user agent u r using???";  
  41.         }  
  42.         </script>  
  43.     </body>  
  44. </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] view plain copy
  1. Thread 5 WebThread, Queue : (null)  
  2. #0  0x387bec96 in WebCore::EventTarget::dispatchEvent(WTF::PassRefPtr<WebCore::Event>) ()  
  3. #1  0x389a8a50 in WebCore::DeviceMotionController::didChangeDeviceMotion(WebCore::DeviceMotionData*) ()  
  4. #2  0x389a83cc in WebCore::DeviceMotionClientIOS::motionChanged(double, double, double, double, double, double, double, double, double) ()  
  5. #3  0x38974b0a in __48-[CoreMotionManager sendMotionData:withHeading:]_block_invoke_0 ()  

PS:

1. Mac WebKit的类还留在iOS版里冗余着,根本没用,例如WebDeviceOrientation。

2. 需要真机调试,模拟器不支持Core Motion。



转载:http://blog.youkuaiyun.com/hursing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值