最近在看设备传感器的API,当然也少不了研究一下让微信称神的“摇一摇”了。关于“摇一摇”的实现,网上很多资料所以不详细说了,但总是有布局、效果不全等各种问题,所以作为一名资深copypaster,代码肯定是要贴的: 源码在此
手机扫二维码看看效果,支持Chrome、Safari、微信(新版):
核心代码是这一段:
this.deviceMotionHandler = function(eventData) { var acceleration = eventData.acceleration; var curTime = new Date().getTime(); ((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; } };
注意点: 这里加了一个摇一摇的音效,移动端关于音频的坑太多,想必各位也是碰到不少。本次的坑是即使调用了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><h2>准备好了吗?<br />点击屏幕开始"摇"!</h2></div> <div> <div> <div></div> </div> <div> <a href="http://www.cnblogs.com/qieguo/"><img src="source/000.png"/></a> </div> <div></div> </div>
效果图:
以上实现了“摇一摇”效果,但以楼主当然不会到此为止。下面是楼主失败而有益的探索(“有益”二字可无视)
楼主的瞎搞
其实楼主是一个吃饭都不想动手的重度懒癌患者,拿着手机看得正爽的时候还要我伸出中指去点击屏幕或者滑动,真的好累啊。。。特别是在躺着的时候,拇指是一个受力点,既要支撑手机还要伸出去滑动屏幕,很不自然。所以,为什么不能甩一甩就翻页呢? 比如说下面的场景:
分析:
这个需求貌似很简单的样子,加速度是有方向的,直接判断x轴加速度正负不就能判断是左甩还是右甩了吗? 摇一摇的代码稍微改改貌似就能实现了呢,窃喜~~~然而,理想总是太丰满,而现实却太骨感。无论我们往哪个方向甩动,最后要停止还是需要加一个阻力,所以一次甩动过程中至少有一次加速度方向的变化。请注意,这里有个“至少”,因为有时候我们要向左甩的时候,可能开始会先向右退一点才左甩的;在刹停的时候也很有可能刹过头了,这里加速度就会有一个抖动。