我正在用HTML5为Windows编写一个移动应用程序。我想检测手机的旋转围绕z轴(我是指旋转,例如,在涂鸦跳转,以使字符跳转到左或右)。
在我的应用程序中,如果我将屏幕向左或向右旋转,屏幕上垂直的线必须保持垂直(在现实世界中的绝对位置)。为了实现这一点,我使用了角度的相对值:每次屏幕旋转一点点,我就会以相同的量旋转直线的点,但是是负的。
当手机躺在桌子上或者几乎是水平的时候,这是完美的,但是如果我在我面前看手机的话,这种行为就不那么精确了。无论如何,这当然不是什么大问题,因为大多数用户都是自上而下地观看手机,但是像涂鸦跳转这样的游戏在这种情况下也表现得很完美。
下面是代码的一部分:
window.addEventListener("deviceorientation", handleOrientation, true);
function handleOrientation(event) {
alphaDiff = Math.floor(event.alpha) - alphaOld;
alphaOld = Math.floor(event.alpha);
//Rotation of the vertical line (x1,y1) - (x2,y2) around the center of the screen
var newPoint = rotate(225, 400, x1, y1, alphaDiff);
x1 = newPoint[0];
y1 = newPoint[1];
newPoint = rotate(225, 400, x2, y2, alphaDiff);
x2 = newPoint[0];
y2 = newPoint[1];
}
function rotate(cx, cy, x, y, angle) {
var radians = (Math.PI / 180) * angle;
cos = Math.cos(radians);
sin = Math.sin(radians);
nx = (cos * (x - cx)) - (sin * (y - cy)) + cx;
ny = (sin * (x - cx)) + (cos * (y - cy)) + cy;
return [nx, ny];
}发布于 2017-01-07 00:20:43
您是否尝试过beta (x轴)或gamma (y轴)?
例如:
function handleOrientation(event) {
var absolute = event.absolute;
var alpha = event.alpha; // z-axis
var beta = event.beta; // x-axis
var gamma = event.gamma; // y-axis
// Do stuff with the new orientation data
}解释取向值 为每个轴报告的值表示参照标准坐标框架围绕给定轴的旋转量。
DeviceOrientationEvent.alpha值表示设备围绕z轴的运动,以从0到360不等的度数表示。DeviceOrientationEvent.beta值表示设备围绕x轴的运动,以从-180到180不等的度数表示。这代表了设备的前后运动。DeviceOrientationEvent.gamma值表示设备围绕y轴的运动,以从-90到90不等的度数表示。这表示设备从左到右的运动。

它也值得检查浏览器兼容性的这个API。
除了deviceorientation,您还可以检查compassneedscalibration和devicemotion。有关deviceorientation的详细信息,请参阅MDN。
发布于 2017-01-07 10:26:24
beta和gamma的结合似乎带来了相当好的结果。基本上,我将这些值规范化到一个特定的范围,并得到这个比率。
window.addEventListener("deviceorientation", function(event){
var b = Math.abs(event.beta)/90;
if(b>1) b = 2-b;
var g = event.gamma/90;
if(Math.abs(event.beta)>90) g = -g;
var x = g/Math.max(0.25,b);
});最后的值在x中,正数表示右边,负数表示左。它适用于水平或任何角度面对你的手机。
更新:使检测工作在一个垂直位置,代码计算手机的倾斜程度和方向。当手机向右倾斜时,x中的值总是为正数,如果向左倾斜,则为负值。
此示例显示屏幕中央的一个蓝色框,并将其移动到电话倾斜的任何方向:
<!DOCTYPE html>
<html>
<head><meta name="viewport" content="width=1000,user-scalable=no"/></head>
<body style="margin:0">
<pre id="log" style="font-size:4em;"></pre>
<div id="box" style="background:#69c;width:100px;height:100px;position:relative;left:450px"></div>
<script>
var box = document.getElementById("box");
var log = document.getElementById("log");
var smoothx = 0;
window.addEventListener("deviceorientation", function(event){
var b = Math.abs(event.beta)/90;
if(b>1) b = 2-b;
var g = event.gamma/90;
if(Math.abs(event.beta)>90) g = -g;
var x = g/Math.max(0.25,b);
smoothx = smoothx*0.7+x*0.3;
box.style.left = Math.max(0, Math.min(900, smoothx*500+450))+"px";
log.innerText = x.toFixed(1)+"\n"+smoothx.toFixed(1);
});
</script>
</body>
</html>因为传感器似乎对运动非常敏感,所以我实现了一个简单的平滑,在smoothx中给出了一个更稳定的值。直接值使用x,而不平滑。
https://stackoverflow.com/questions/41433194
复制相似问题