HTML5 摇一摇加强版之一次失败的探索
最近在看设备传感器的API,当然也少不了研究一下让微信称神的“摇一摇”了。关于“摇一摇”的实现,网上很多资料所以不详细说了,但总是有布局、效果不全等各种问题,所以作为一名资深copypaster,代码肯定是要贴的: 源码在此
手机扫二维码看看效果,支持Chrome、Safari、微信(新版):

核心代码是这一段:
this.deviceMotionHandler = function(eventData) {
var acceleration = eventData.acceleration;
var curTime = new Date().getTime();
//检测频率:每100ms一次
if ((curTime - that.last_update) > 100) {
var diffTime = curTime - that.last_update;
that.last_update = curTime;
that.x = acceleration.x;
that.y = acceleration.y;
that.z = acceleration.z;
var speed = Math.abs(that.x + that.y + that.z - that.last_x - that.last_y - that.last_z) / diffTime * 10000;
if (speed > that.SHAKE_THRESHOLD) {
//do something
that.shakeAudio.play(); //摇一摇音效
window.navigator.vibrate(200); //振动效果
that.shakeEffect.className = 'shake-box shaking'; //摇一摇图片动态
clearTimeout(shakeTimeout);
var shakeTimeout = setTimeout(function() {
that.shakeEffect.className = 'shake-box';
},4000);
}
that.last_x = that.x;
that.last_y = that.y;
that.last_z = that.z;
}
};
原理: 以100ms的间隔去扫描加速度计,当检测到加速度发生突变(变化率大于阀值)时,就可以认为此时在甩动手机。由公式可以看到,这里检测的是3个方向的加速度,所以无论往什么方向甩都可以触发摇一摇效果。
注意点: 这里加了一个摇一摇的音效,移动端关于音频的坑太多,想必各位也是碰到不少。本次的坑是即使调用了play也无法播放,解决办法是让用户操作第一次播放或者加载,具体来说就是绑定一个事件,如下。而且加载需要一定时间,这里本来应该再做缓冲处理,但我没有,所以第一次播放会有很明显的延迟。
window.addEventListener('touchstart',function () {
if ( !shake1.audioLoaded ) {
shake1.shakeAudio.load(); //load事件必须由用户触发
shake1.audioLoaded = true;
}
}, false);
布局方面: 布局方面尝试使用了CSS3的弹性盒子,但是万万没想到先进的X5内核居然仅支持 display: -webkit-box; 所以这里需要多写一套兼容的样式。动态效果本来想用 transition 凑合一下,看了效果还是过不了自己这关,最后还是换成 animation 实现。transition的问题是撑开和收缩时边框的行为不对,用动画就比较好解决了。布局需要注意的是:背景图的上半部需要多加一层嵌套实现自适应。另外,微信的边框还有阴影,这些细节咱们暂时先忽略了。HTML结构如下:
<div class="bodymask"><h2>准备好了吗?<br />点击屏幕开始"摇"!</h2></div>
<div class="shake-box">
<div class="shake-upside">
<div class="shake-upside-inner"></div>
</div>
<div class="shake-backimage">
<a href="http://www.cnblogs.com/qieguo/"><img id="id-shake-image" src="source/000.png"/></a>
</div>
<div class="shake-downside"></div>
</div>
效果图:

以上实现了“摇一摇”效果,但以楼主当然不会到此为止。下面是楼主失败而有益的探索(“有益”二字可无视)
楼主的瞎搞
其实楼主是一个吃饭都不想动手的重度懒癌患者,拿着手机看得正爽的时候还要我伸出中指去点击屏幕或者滑动,真的好累啊。。。特别是在躺着的时候,拇指是一个受力点,既要支撑手机还要伸出去滑动屏幕,很不自然。所以,为什么不能甩一甩就翻页呢? 比如说下面的场景:

分析:
这个需求貌似很简单的样子,加速度是有方向的,直接判断x轴加速度正负不就能判断是左甩还是右甩了吗? 摇一摇的代码稍微改改貌似就能实现了呢,窃喜~~~然而,理想总是太丰满,而现实却太骨感。无论我们往哪个方向甩动,最后要停止还是需要加一个阻力,所以一次甩动过程中至少有一次加速度方向的变化。请注意,这里有个“至少”,因为有时候我们要向左甩的时候,可能开始会先向右退一点才左甩的;在刹停的时候也很有可能刹过头了,这里加速度就会有一个抖动。



想象总是没说服力,我们还是看看数据吧。当然这里先利用摇一摇类似的筛选规则来去掉非甩动的动作。当检测到加速度发生突变(变化率大于阀值)时认为发生了一次甩动,这时候输出 x 轴的加速度值来看看,扫描频率设置为100ms的时候数据如下:


上面分别是左甩和右甩时候的数据,根据这个数据特点,判断每一个周期的第一个符合条件的加速度正负就可以判断甩动的方向了,楼主这里定义每个甩动周期为1s。
var speed = Math.abs(that.x + that.y + that.z - that.last_x - that.last_y - that.last_z) / diffTime * 10000;
if (speed > that.SHAKE_THRESHOLD) {
if ((curTime - that.last_catch) > 1000) {
if (that.x > 5) {
output.innerHTML += '右甩x:' + that.x + '<br/>'; //加速度向右,右甩
that.last_catch = curTime;
} else if( that.x < -5) {
output.innerHTML += '左甩x:' + that.x + '<br/>'; //加速度向左,左甩
that.last_catch = curTime;
}
}
}
理论上这个是可以筛选掉不适合的加速度数据了,测试如下:


看起来像是得到了准确的结果,但不同人有不同的习惯、力度,上面的方法并不能很好的得到最准确的办法。
更为准确的办法应该是求出x的位移,再加上 x轴加速度变化判断是否甩动,两者结合就可以很好的判断甩动方向了。这里位移只要求能判断左右,所以直接用高中物理的公式即可。但是,在测试了 n 次之后,我才开始想,这个需求是真实存在的吗?还是说只存在我的臆想里面? 突然想起红衣教主的话,很多人啊都是掌握一门技术之后呢就会把这个技术包装成一个产品,还会强行为这个产品适配很多需求,但这些需求都是YY,都是伪需求!
真理!老周这一针见血啊!
不过呢,加速度计和陀螺仪还是非常好玩的东西,好好利用它们还是可以实现很多有趣的东西,比如说这个:AIWI使用手机玩体感游戏。
只要你能利用加速度计和陀螺仪计算出空间中的运动轨迹,那这一切都好办了,不过要得到比较好的精度可不能用高中物理那种简单的时域积分哦,这个楼主就不敢强行装逼了,有兴趣的同学自行搜索哈。
以上,这一篇都实在太水了,还是放图吧。

(图片出处:小周同学,转载请注明)
原创文章,转载请注明出处!本文链接:http://www.cnblogs.com/qieguo/p/5448786.html
HTML5 摇一摇加强版之一次失败的探索的更多相关文章
- HTML5实现摇一摇
一.原理: 利用devicemotion获取移动速度,得到device移动时相对之前某个时间的差值比 二.效果图: 三.源码: //先判断设备是否支持HTML5摇一摇功能 if (window.Dev ...
- html5实现摇一摇功能
原理:使用DeviceMotion实现,关于DeviceMotion介绍可以查看 https://developer.mozilla.org/en-US/docs/Web/Reference/Even ...
- html5实现微信摇一摇功能
在HTML5中,DeviceOrientation特性所提供的DeviceMotion事件封装了设备的运动传感器时间,通过改时间可以获取设备的运动状态.加速度等数据(另还有deviceOrientat ...
- html5摇一摇[转]
写在前面 年底了,有些公司会出一个摇奖的活动,今天在家没事就搜了一下这方面的资料. 原文地址:http://www.cnblogs.com/waitingbar/p/4682215.html 测试 效 ...
- 用HTML5实现手机摇一摇的功能(转)
在百度开发者大会上我介绍过HTML5另外一个重要特性就是DeviceOrientation,它将底层的方向传感器和运动传感器进行了高级封装,提供了DOM事件的支持.这个特性包括两种事件: 1.devi ...
- Adobe Edge Animate --使用HTML5实现手机摇一摇功能
Adobe Edge Animate --使用HTML5实现手机摇一摇功能 版权声明: 本文版权属于 北京联友天下科技发展有限公司. 转载的时候请注明版权和原文地址. HTML5的发展日新月异,其功能 ...
- js html5 仿微信摇一摇
看微信摇一摇之后忽然想知道他是怎么写的.于是就在网上查了一些资料,有些是借鉴别人的.大家共同学习啊 先放代码 <body onload="init()"> <p& ...
- HTML5实现“摇一摇”效果
在HTML5中,DeviceOrientation特性所提供的DeviceMotion事件封装了设备的运动传感器时间,通过改时间可以获取设备的运动状态.加速度等数据(另还有deviceOrientat ...
- 利用HTML5+Socket.io实现摇一摇控制PC端歌曲切换
我比较喜欢听音乐,特别是周末的时候,电脑开着百度随心听fm,随机播放歌曲,躺在床上享受.但碰到了一个烦人的事情,想切掉不喜欢的曲子,还得起床去操作电脑换歌.于是思考能不能用手机控制电脑切换歌曲,经过一 ...
随机推荐
- Hadoop 中利用 mapreduce 读写 mysql 数据
Hadoop 中利用 mapreduce 读写 mysql 数据 有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...
- 笔记:Binder通信机制
TODO: 待修正 Binder简介 Binder是android系统中实现的一种高效的IPC机制,平常接触到的各种XxxManager,以及绑定Service时都在使用它进行跨进程操作. 它的实现基 ...
- java中的锁
java中有哪些锁 这个问题在我看了一遍<java并发编程>后尽然无法回答,说明自己对于锁的概念了解的不够.于是再次翻看了一下书里的内容,突然有点打开脑门的感觉.看来确实是要学习的最好方式 ...
- 微软发布正式版SQL Server 2016
微软于今天在SQL 官方博客上宣布 SQL Server 数据库软件的正式发布版本(GA),历时一年多,微软为该软件发布了多个公共预览版和候选版本,而今天最终版本终于上线了.在博客中,微软数据集团的企 ...
- iOS---iOS10适配iOS当前所有系统的远程推送
一.iOS推送通知简介 众所周知苹果的推送通知从iOS3开始出现, 每一年都会更新一些新的用法. 譬如iOS7出现的Silent remote notifications(远程静默推送), iOS8出 ...
- ZKWeb网页框架1.3正式发布
本次更新的内容有 更新引用包版本 Microsoft.AspNetCore.Hosting.Abstractions 1.1.0 Microsoft.AspNetCore.Http.Abstracti ...
- ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由
原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...
- ASP.NET MVC——模型绑定
这篇文章我们来讲讲模型绑定(Model Binding),其实在初步了解ASP.NET MVC之后,大家可能都会产生一个疑问,为什么URL片段最后会转换为例如int型或者其他类型的参数呢?这里就不得不 ...
- arcgis api for js入门开发系列六地图分屏对比(含源代码)
上一篇实现了demo的地图标绘模块,本篇新增地图地图分屏对比模块,截图如下(源代码见文章底部): 对效果图的简单介绍一下,在demo只采用了两分屏对比,感兴趣的话,可以在两分屏的基础上拓展,修改css ...
- 「译」JUnit 5 系列:环境搭建
原文地址:http://blog.codefx.org/libraries/junit-5-setup/ 原文日期:15, Feb, 2016 译文首发:Linesh 的博客:环境搭建 我的 Gith ...