重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇“HTML5怎么制作一个重力感应球”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“HTML5怎么制作一个重力感应球”文章吧。
创新互联是专业的中山网站建设公司,中山接单;提供成都网站设计、成都做网站,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行中山网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
重力传感器是一个非常常见的内置在智能手机等移动设备中的传感器,基本作用就是获得移动设备的重心。当移动设备倾斜或翻转时,重心会发生变化,而重力传感器将如实地记录下重心变化的过程并通过数据反映出来。
由于安全问题,浏览器可能会默认关闭一些配置,因此读者需要从欧朋浏览器地址栏中输入opera:config后回车,找到需要的相关参数,进行调整
如果你在测试时,发现无法监测到deviceorientation传出来的值,有可能是因为关闭了对deviceorientation的支持,那你可以试着照上图所示的方式,在地址栏中输入opera:config,回车,然后找到Orientation选项并勾选上
1. 了解重力传感器
传感器是移动互联网Web App开发中非常重要的一个设备,涉及多个应用概念。在HTML5的Device API中,DeviceOrientation事件规范提供了3个DOM事件,分别是:deviceorientation、compassneedscalibration和devicemotion。本节主要讲解的是deviceorientation。
DeviceOrientation规范定义的是返回alpha、beta和gamma三个值,如下面的代码所示:
window.addEventListener("deviceorientation", function(event){
//返回值event.alpha、event.beta、event.gamma
}, true);
当设备水平放在桌面上时,其event返回的值如下:
{alpha: 90,
beta: 0,
gamma: 0};
而此时,其设备的朝向值应为360-alpha(当设备翻转时,以此公式为基础进行朝向运算),
当设备的转动变成以x轴为中心自转时,其event返回的值如下:
{alpha: 90,
beta: 90,
gamma: 0};
当设备的转动变成以z 轴为中心自转时,则alpha值发生变化,
当设备的转动变成以y 轴为中心自转时,则gamma值发生变化,
当DeviceOrientation规范的Devicemotion事件的加速度计还允许有重力时,则会出现:
{x: 0,
y: 0,
z: 9.81};
而这时,如果设备处于自由落体的情况时,它的值应该是:
{x: 0,
y: 0,
z: -9.81};
如果设备在高速行驶的汽车中时,它的值应该是(这是复杂应用,目前还没有良好的支持,
有兴趣的读者可以继续深入研究):
{acceleration: {x: v^2/r, y: 0, z: 0},
accelerationIncludingGravity: {x: v^2/r, y: 0, z: 9.81},
rotationRate: {alpha: 0, beta: 0, gamma:-v/r*180/pi} };
2. 重力感应球示例
为了让读者更好地了解重力传感器,建立起感性的认识,我们通过重力感应球的示例来展示重力传感器的开发过程和技巧。
重力传感器示例的代码如代码如下:
style="z-index:1000;position:absolute;left:0px;top:30px;"> onclick="showhelp('')">
function hiddeDiv(id){
document.getElementById('helpme').style.display='none';
}
function showhelp(){
document.getElementById('helpme').style.display='';
}
var cur_x = 0;
var cur_y = 0;
var ball_radius = 50; //球的半径,用来判断是否靠近边界,进行碰撞检测用
var initialized = false; //初始化的值
var ww;
var wh;
var speed_x = 0;
var speed_y = 0;
var accel_x;
var accel_y;
var friction_accel = 0.02; //摩擦系数
var interval = 33; //毫秒数, 约为30帧每秒
var bg_color = "#EEEEEE";
var fg_color = "#333";
var absorbing_rate = 0.5; //弹力消耗比例
var gunball=new Image();
gunball.src="opera_ball.png"; //实例化的滚球的图像
var opera_pix_bg=new Image();
opera_pix_bg.src="opera_pix_bg2.png"; //实例化的背景图
function inSameDirection(a, b){ //方向判断函数
return a > 0 && b > 0 || a <= 0 && b <= 0;
}
function getCurpos(cur_pos, speed, accel, boundary){ //当前位置判断函数
if(speed == 0 &&Math.abs(accel) <= friction_accel)
return [cur_pos, speed];
start_speed = speed;
f_accel = (speed > 0 ? -friction_accel:friction_accel); //摩擦力导致速度变慢
speed += accel + f_accel; //速度的方向被改变了
if(!inSameDirection(f_accel, accel) &&
!inSameDirection(f_accel, start_speed) &&
!inSameDirection(start_speed, speed)){
//因为摩擦,球的速度逐渐为0
speed = 0;
}
cur_pos += (start_speed + speed)/2; //边界检测
if(cur_pos> boundary - ball_radius){
cur_pos= boundary - ball_radius;
speed = -speed * absorbing_rate;
}
else if(cur_pos < 0){
cur_pos = 0;
speed = -speed * absorbing_rate;
}
return [cur_pos, speed];
}
function physics(){ //物理运动计算函数
var x = getCurpos(cur_x, speed_x, accel_x, ww);
cur_x = x[0];
speed_x = x[1];
var y = getCurpos(cur_y, speed_y, accel_y, wh);
cur_y = y[0];
speed_y = y[1];
}
function paint(){ //绘图函数
var ball_canvas = document.getElementById('ball');
var ctx = ball_canvas.getContext('2d');
physics(); //引入物理运动计算的函数
ctx.drawImage(opera_pix_bg, 0,0, ww, wh );
ctx.drawImage(gunball, cur_x,cur_y, 50, 50 );
setTimeout("paint()", interval);
}
function clearCanvas(){ //擦除画布的函数
var ball_canvas = document.getElementById('ball');
var ctx = ball_canvas.getContext('2d');
}
function update(evt){ //更新画布的函数
var ball_canvas = document.getElementById('ball');
if(ball_canvas.width != window.outerWidth ||
ball_canvas.height != window.outerHeight){
ball_canvas.width = window.outerWidth;
ball_canvas.height = window.outerHeight;
clearCanvas();
}
ww = ball_canvas.width;
wh = ball_canvas.height;
//根据重力传感器的值计算加速度
accel_x = Math.sin(evt.gamma/180 * Math.PI);
accel_y = Math.sin(evt.beta/180 * Math.PI);
if(!initialized){
cur_x = ww/2 + ball_radius; //滚球当前位置的x坐标值
cur_y = wh/2 + ball_radius; //滚球当前位置的y坐标值
initialized = true;
clearCanvas();
paint(); //调用绘图函数
}
}
function preload(){
var ball_canvas = document.getElementById('ball');
if(ball_canvas.width != window.outerWidth ||
ball_canvas.height != window.outerHeight){
ball_canvas.width = window.outerWidth;
ball_canvas.height = window.outerHeight;
}
ww = ball_canvas.width;
wh = ball_canvas.height;
paint();
}
preload();
window.addEventListener('deviceorientation', update, true);
晃动、翻转设备时,球会随着设备的变动而滚动弹跳。本代码的执行效果如下图:
3. 本例小结
本例是众多传感器设备通过HTML5标准在浏览器上实现的一个典型案例。到目前为止,如果开发者要做重力传感器的实验,又买不起iPhone或者iPad的话,搞个便宜的Android系统手机,装上欧朋H5就可以试验了。
在开发重力传感器的时候,新手往往会忽略几个问题,在此我们特意提出来供读者引以为鉴。
(1) 传感器得出来的值是非稳定态的,往往有噪声数据,因此,如果开发者直接使用传感器传过来的值进行绘图,一定会出现滚球闪动和瞬间不受控的现象。很多开发者在滤波面前往往一愁莫展,网上大量的各种滤波算法都是有用的,而且是合理的,例如平均值滤波、去除最大值和最小值的滤波、加权平均滤波,甚至卷积分滤波等。但是,经过实践,我们总结出一个很有效的。
小经验 通过setInterval这样的定时器去取值,把帧数定在30帧左右,就可以实现99%以上的完美滤波。我们把这个方法称为时间点抽样滤波。
(2) iOS系统里(iPhone、iPad和iPod)的Safari在直接获取传感器数据时,往往没有噪声,原因是浏览器已经消过噪了。这是好事,也是坏事。好事是开发者不用操心传感器的示波不稳定问题。坏事是开发者得到的数据都是经过过滤的,而且没有办法得到第一手数据,往往在特殊情况下不利。在摇动、晃动等行为发生时,用重力传感器是不合适的。在标准中, devicemotion事件可以判断摇动、晃动等行为的。
虽然在标准中有提示可以通过加速度和角度来计算摇动、晃动等行为,但很多开发者可能会不适应,建议使用devicemotion事件。
以上就是关于“HTML5怎么制作一个重力感应球”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注创新互联行业资讯频道。