我比较喜欢听音乐,特别是周末的时候,电脑开着百度随心听fm,随机播放歌曲,躺在床上享受。但碰到了一个烦人的事情,想切掉不喜欢的曲子,还得起床去操作电脑换歌。于是思考能不能用手机控制电脑切换歌曲,经过一段事件的思考,绝对采用html5+socket.io来实现这个功能。首先我把该功能的实现拆分为以下几个步骤:
1.移动端前端页面+脚本逻辑实现
2.PC端前端页面+脚本逻辑实现
3.后台逻辑实现
4.加入socket.io实现长连接
5.实现移动端控制PC端逻辑
1、移动端页面脚本的实现
html页面编写
仿造微信摇一摇的页面,实现一个类似的界面,如下所示:
当我们摇手机的时候,会做一个动画,中间的图案一分为二,上半部向上运动然后回来,下半部亦同理,如下所示:
移动端界面
html代码(shake.html):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> <title>摇一摇切歌</title> <link href="https://www.jb51.net/shake.css"> </head> <body> <div> <div></div> <div></div> <div></div> </div> <div> </div> <div> <audio src="https://www.jb51.net/new_silent.mp3"></audio> <audio src="https://www.jb51.net/new_silent.mp3"></audio> </div> <script type="text/javascript" src="https://www.jb51.net/socket.io.js"></script> <script src="https://www.jb51.net/shake.js"></script> </body> </html>
样式表(shake.css):
html,body{ width:100%; height:100%; background-color: #000; margin:0; overflow: hidden; } .wrap{ position: absolute; left:50%; top:50%; width:132px; height: 132px; -webkit-transform: translate(-50%,-50%); transform: translate(-50%,-50%); } .hand{ position: absolute; left:0; width:100%; height: 50%; background: url(shake.png) no-repeat #000; background-size: 132px 132px; } .above-hand{ top:0; background-position: 0 0; } .below-hand{ bottom:0; background-position: 0 -66px; } .inner{ position:absolute; top:50%; left:50%; width: 50px; height: 90px; background: url(inner.png) no-repeat 0 0; background-size: 50px 90px; -webkit-transform: translate(-50%,-50%); transform: translate(-50%,-50%); } .above-hand:after,.below-hand:before{ display: none; content:''; position:absolute; left:-100vw; width:200vw; height: 2px; background-color: #BABDC1; } .above-hand:after{ bottom:0; } .below-hand:before{ top:0; } .wrap.active .above-hand{ -webkit-animation: up 1.5s ease; animation: up 1s ease; } .wrap.active .below-hand{ -webkit-animation: down 1.5s ease; animation: down 1s ease; } .wrap.active .above-hand:after,.wrap.active .below-hand:before{ display: block; } .tip{ position: absolute; bottom: 30px; left: 10px; color: #fff; font-family: '楷体'; text-align: center; right: 10px; height: 32px; line-height: 32px; background-color: rgba(255,255,255,.4); border-radius: 3px; } .tip.active{ -webkit-animation: jump 1.5s linear; animation: jump 1s linear; }
脚本逻辑
接下来是移动端JS脚本逻辑的实现,摇一摇的实现需借助html5新增的devicemotion事件,获取设备在位置和方向上的改变速度的相关信息,该事件的基本使用如下:
if(window.DeviceMotionEvent){ window.addEventListener('devicemotion',handler,!1); }else{ alert('你的浏览器不支持摇一摇功能.'); }
devicemotion事件对象中有一个accelerationIncludingGravity属性,该属性包括:一个包含x、y 和z 属性的对象,在考虑z 轴自然重力加速度的情况下,告诉你在每个方向上的加速度。该API的具体使用大家可以参考网上的资料,非常多,这里就不重复了。
摇一摇的具体逻辑如下:
function handler(e){ var current = e.accelerationIncludingGravity; var currentTime; var timeDifference; var deltaX = 0; var deltaY = 0; var deltaZ = 0; //记录上一次设备在x,y,z方向上的加速度 if ((lastX === null) && (lastY === null) && (lastZ === null)) { lastX = current.x; lastY = current.y; lastZ = current.z; return; } //得到两次移动各个方向上的加速度绝对差距 deltaX = Math.abs(lastX - current.x); deltaY = Math.abs(lastY - current.y); deltaZ = Math.abs(lastZ - current.z); //当差距大于设定的阀值并且时间间隔大于指定阀值时,触发摇一摇逻辑 if (((deltaX > threshold) && (deltaY > threshold)) || ((deltaX > threshold) && (deltaZ > threshold)) || ((deltaY > threshold) && (deltaZ > threshold))) { currentTime = new Date(); timeDifference = currentTime.getTime() - lastTime.getTime(); if (timeDifference > timeout) { dealShake(); lastTime = new Date(); } } lastX = current.x; lastY = current.y; lastZ = current.z; }