I have recently come across a few websites that seems to access the accelerometer or gyroscope on my laptop, detecting changes in orientation or movement.
最近,我遇到了一些网站,它们似乎可以访问我笔记本上的加速度计或陀螺仪,检测方向或运动的变化。
How is this done? Must I subscribe to some kind of event on the window
object?
这是怎么做的?我必须订阅窗口对象上的某种事件吗?
On which devices (laptops, mobile phones, tablets) is this known to work?
在哪些设备(笔记本电脑、手机、平板电脑)上,这是已知的工作方式?
NB: I actually already know (part of) the answer to this question, and I am going to post it right away. The reason that I am posting the question here, is to let everyone else know that accelerometer data is available in Javascript (on certain devices) and to challenge the community to post new findings on the subject. Currently, there seems to be almost no documentation of these features.
NB:我已经知道这个问题的部分答案了,我马上就把它贴出来。我在这里发布这个问题的原因是,让其他人知道在Javascript(在某些设备上)可以使用加速度计数据,并要求社区发布关于这个主题的新发现。目前,似乎几乎没有这些特性的文档。
3 个解决方案
#1
168
There are currently three distinct events which may or may not be triggered when the client devices moves. Two of them are focused around orientation and the last on motion:
目前有三个不同的事件,当客户端设备移动时,可能会触发,也可能不会触发。其中两项关注方向,最后一项关注运动:
-
ondeviceorientation
is known to work on the desktop version of Chrome, and most Apple laptops seems to have the hardware required for this to work. It also works on Mobile Safari on the iPhone 4 with iOS 4.2. In the event handler function, you can accessalpha
,beta
,gamma
values on the event data supplied as the only argument to the function.ondeviceorientation被认为可以在桌面版的Chrome上工作,而大多数苹果笔记本电脑似乎都有运行这一功能所需的硬件。它也适用于iphone4的移动Safari和ios4.2。在事件处理程序函数中,您可以访问作为函数唯一参数提供的事件数据上的alpha、beta、gamma值。
-
onmozorientation
is supported on Firefox 3.6 and newer. Again, this is known to work on most Apple laptops, but might work on Windows or Linux machines with accelerometer as well. In the event handler function, look forx
,y
,z
fields on the event data supplied as first argument.Firefox 3.6和更新版本支持onmozorientation。同样,这在大多数苹果笔记本电脑上都是众所周知的,但也可能在Windows或Linux机器上使用加速计。在事件处理程序函数中,在作为第一个参数提供的事件数据上查找x、y、z字段。
-
ondevicemotion
is known to work on iPhone 3GS + 4 and iPad (both with iOS 4.2), and provides data related to the current acceleration of the client device. The event data passed to the handler function hasacceleration
andaccelerationIncludingGravity
, which both have three fields for each axis:x
,y
,z
ondevicemotion支持iPhone 3GS + 4和iPad(都支持iOS 4.2),并提供与客户端设备当前加速有关的数据。传递给处理器函数的事件数据具有加速度和加速度,包括重力,每个轴都有三个字段:x、y、z。
The "earthquake detecting" sample website uses a series of if
statements to figure out which event to attach to (in a somewhat prioritized order) and passes the data received to a common tilt
function:
“地震探测”示例网站使用一系列if语句来确定要附加到哪个事件(按某种优先级排序),并将接收到的数据传递给一个通用的tilt函数:
if (window.DeviceOrientationEvent) {
window.addEventListener("deviceorientation", function () {
tilt([event.beta, event.gamma]);
}, true);
} else if (window.DeviceMotionEvent) {
window.addEventListener('devicemotion', function () {
tilt([event.acceleration.x * 2, event.acceleration.y * 2]);
}, true);
} else {
window.addEventListener("MozOrientation", function () {
tilt([orientation.x * 50, orientation.y * 50]);
}, true);
}
The constant factors 2 and 50 are used to "align" the readings from the two latter events with those from the first, but these are by no means precise representations. For this simple "toy" project it works just fine, but if you need to use the data for something slightly more serious, you will have to get familiar with the units of the values provided in the different events and treat them with respect :)
常数因子2和50被用来将后两个事件的读数与第一个事件的读数“对齐”,但它们绝不是精确的表示。对于这个简单的“玩具”项目,它工作得很好,但是如果您需要将数据用于稍微严重一些的事情,您必须熟悉在不同事件中提供的值的单位,并以尊重的态度对待它们:)
#2
18
Can't add a comment to the excellent explanation in the other post but wanted to mention that a great documentation source can be found here.
不能对另一篇文章中出色的解释添加注释,但是想要提到的是,这里可以找到一个很棒的文档来源。
It is enough to register an event function for accelerometer like so:
为加速计注册一个事件函数就足够了:
if(window.DeviceMotionEvent){
window.addEventListener("devicemotion", motion, false);
}else{
console.log("DeviceMotionEvent is not supported");
}
with the handler:
处理程序:
function motion(event){
console.log("Accelerometer: "
+ event.accelerationIncludingGravity.x + ", "
+ event.accelerationIncludingGravity.y + ", "
+ event.accelerationIncludingGravity.z
);
}
And for magnetometer a following event handler has to be registered:
对于磁强计,必须注册以下事件处理器:
if(window.DeviceOrientationEvent){
window.addEventListener("deviceorientation", orientation, false);
}else{
console.log("DeviceOrientationEvent is not supported");
}
with a handler:
处理程序:
function orientation(event){
console.log("Magnetometer: "
+ event.alpha + ", "
+ event.beta + ", "
+ event.gamma
);
}
There are also fields specified in the motion event for a gyroscope but that does not seem to be universally supported (e.g. it didn't work on a Samsung Galaxy Note).
陀螺仪的运动事件中也指定了一些字段,但似乎并没有得到普遍的支持(例如,三星Galaxy Note就没有这个字段)。
There is a simple working code on GitHub
GitHub上有一个简单的工作代码
#3
1
Usefull fallback here: https://developer.mozilla.org/en-US/docs/Web/Events/MozOrientation
这里有用回退:https://developer.mozilla.org/en-US/docs/Web/Events/MozOrientation
function orientationhandler(evt){
// For FF3.6+
if (!evt.gamma && !evt.beta) {
evt.gamma = -(evt.x * (180 / Math.PI));
evt.beta = -(evt.y * (180 / Math.PI));
}
// use evt.gamma, evt.beta, and evt.alpha
// according to dev.w3.org/geo/api/spec-source-orientation
}
window.addEventListener('deviceorientation', orientationhandler, false);
window.addEventListener('MozOrientation', orientationhandler, false);
#1
168
There are currently three distinct events which may or may not be triggered when the client devices moves. Two of them are focused around orientation and the last on motion:
目前有三个不同的事件,当客户端设备移动时,可能会触发,也可能不会触发。其中两项关注方向,最后一项关注运动:
-
ondeviceorientation
is known to work on the desktop version of Chrome, and most Apple laptops seems to have the hardware required for this to work. It also works on Mobile Safari on the iPhone 4 with iOS 4.2. In the event handler function, you can accessalpha
,beta
,gamma
values on the event data supplied as the only argument to the function.ondeviceorientation被认为可以在桌面版的Chrome上工作,而大多数苹果笔记本电脑似乎都有运行这一功能所需的硬件。它也适用于iphone4的移动Safari和ios4.2。在事件处理程序函数中,您可以访问作为函数唯一参数提供的事件数据上的alpha、beta、gamma值。
-
onmozorientation
is supported on Firefox 3.6 and newer. Again, this is known to work on most Apple laptops, but might work on Windows or Linux machines with accelerometer as well. In the event handler function, look forx
,y
,z
fields on the event data supplied as first argument.Firefox 3.6和更新版本支持onmozorientation。同样,这在大多数苹果笔记本电脑上都是众所周知的,但也可能在Windows或Linux机器上使用加速计。在事件处理程序函数中,在作为第一个参数提供的事件数据上查找x、y、z字段。
-
ondevicemotion
is known to work on iPhone 3GS + 4 and iPad (both with iOS 4.2), and provides data related to the current acceleration of the client device. The event data passed to the handler function hasacceleration
andaccelerationIncludingGravity
, which both have three fields for each axis:x
,y
,z
ondevicemotion支持iPhone 3GS + 4和iPad(都支持iOS 4.2),并提供与客户端设备当前加速有关的数据。传递给处理器函数的事件数据具有加速度和加速度,包括重力,每个轴都有三个字段:x、y、z。
The "earthquake detecting" sample website uses a series of if
statements to figure out which event to attach to (in a somewhat prioritized order) and passes the data received to a common tilt
function:
“地震探测”示例网站使用一系列if语句来确定要附加到哪个事件(按某种优先级排序),并将接收到的数据传递给一个通用的tilt函数:
if (window.DeviceOrientationEvent) {
window.addEventListener("deviceorientation", function () {
tilt([event.beta, event.gamma]);
}, true);
} else if (window.DeviceMotionEvent) {
window.addEventListener('devicemotion', function () {
tilt([event.acceleration.x * 2, event.acceleration.y * 2]);
}, true);
} else {
window.addEventListener("MozOrientation", function () {
tilt([orientation.x * 50, orientation.y * 50]);
}, true);
}
The constant factors 2 and 50 are used to "align" the readings from the two latter events with those from the first, but these are by no means precise representations. For this simple "toy" project it works just fine, but if you need to use the data for something slightly more serious, you will have to get familiar with the units of the values provided in the different events and treat them with respect :)
常数因子2和50被用来将后两个事件的读数与第一个事件的读数“对齐”,但它们绝不是精确的表示。对于这个简单的“玩具”项目,它工作得很好,但是如果您需要将数据用于稍微严重一些的事情,您必须熟悉在不同事件中提供的值的单位,并以尊重的态度对待它们:)
#2
18
Can't add a comment to the excellent explanation in the other post but wanted to mention that a great documentation source can be found here.
不能对另一篇文章中出色的解释添加注释,但是想要提到的是,这里可以找到一个很棒的文档来源。
It is enough to register an event function for accelerometer like so:
为加速计注册一个事件函数就足够了:
if(window.DeviceMotionEvent){
window.addEventListener("devicemotion", motion, false);
}else{
console.log("DeviceMotionEvent is not supported");
}
with the handler:
处理程序:
function motion(event){
console.log("Accelerometer: "
+ event.accelerationIncludingGravity.x + ", "
+ event.accelerationIncludingGravity.y + ", "
+ event.accelerationIncludingGravity.z
);
}
And for magnetometer a following event handler has to be registered:
对于磁强计,必须注册以下事件处理器:
if(window.DeviceOrientationEvent){
window.addEventListener("deviceorientation", orientation, false);
}else{
console.log("DeviceOrientationEvent is not supported");
}
with a handler:
处理程序:
function orientation(event){
console.log("Magnetometer: "
+ event.alpha + ", "
+ event.beta + ", "
+ event.gamma
);
}
There are also fields specified in the motion event for a gyroscope but that does not seem to be universally supported (e.g. it didn't work on a Samsung Galaxy Note).
陀螺仪的运动事件中也指定了一些字段,但似乎并没有得到普遍的支持(例如,三星Galaxy Note就没有这个字段)。
There is a simple working code on GitHub
GitHub上有一个简单的工作代码
#3
1
Usefull fallback here: https://developer.mozilla.org/en-US/docs/Web/Events/MozOrientation
这里有用回退:https://developer.mozilla.org/en-US/docs/Web/Events/MozOrientation
function orientationhandler(evt){
// For FF3.6+
if (!evt.gamma && !evt.beta) {
evt.gamma = -(evt.x * (180 / Math.PI));
evt.beta = -(evt.y * (180 / Math.PI));
}
// use evt.gamma, evt.beta, and evt.alpha
// according to dev.w3.org/geo/api/spec-source-orientation
}
window.addEventListener('deviceorientation', orientationhandler, false);
window.addEventListener('MozOrientation', orientationhandler, false);