我比较喜欢听音乐,特别是周末的时候,电脑开着百度随心听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 name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
<title>摇一摇切歌</title>
<link rel="stylesheet" href="shake.css">
</head>
<body>
<div class="wrap" id="wrap">
<div class="inner"></div>
<div class="above-hand hand" id="up"></div>
<div class="below-hand hand" id="bt"></div>
</div>
<div class="tip" id="tip">
</div>
<div style="display: none;">
<audio id="shaking" src="new_silent.mp3"></audio>
<audio id="found" src="new_silent.mp3"></audio>
</div>
<script type="text/javascript" src="socket.io.js"></script>
<script src="shake.js"></script>
</body>
</html>
</div>
样式表(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;
}
</div>
脚本逻辑
接下来是移动端JS脚本逻辑的实现,摇一摇的实现需借助html5新增的devicemotion事件,获取设备在位置和方向上的改变速度的相关信息,该事件的基本使用如下:
if(window.DeviceMotionEvent){
window.addEventListener('devicemotion',handler,!1);
}else{
alert('你的浏览器不支持摇一摇功能.');
}
</div>
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;
}
</div>
由于摇一摇需要播放摇一摇的声音以及切换歌曲成功后的声音,但由于手机大部分是禁止音频的自动播放,必须需要用户真实点击才能播放音频。这里没有彻底的解决办法,只是换了一个思路,利用用户随时触摸屏幕的习惯,对document进行touchstart事件监听。当用户触摸到屏幕时,先播放一个1S的无声音频,接着将touchstart事件移除,然后摇一摇的时候切换声音源,播放摇一摇的声音,这样便可以达到类似的目的。代码如下所示:
document.addEventListener('touchstart',autoplay,!1);
function autoplay(){
shaking.play();
found.play();
document.removeEventListener('touchstart',autoplay);
}
</div>
2、PC端前端页面脚本逻辑实现
html文档
PC端界面也是仿的网上的一个html5音乐播放器的界面,效果如下所示:

HTML(shake_pc.html)布局代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>随心听</title>
<meta name="referrer" content="never">
<link rel="stylesheet" href="reset2.0.css">
<link rel="stylesheet" href="shake_pc.css">
</head>
<body>
<!-- 控制背景图效果 -->
<div class="bg" id="bg">
</div>
<div class="music-player">
<!-- 歌曲信息 -->
<div class="info">
<div class="song-name" id="songName"></div>
<div class="author" id="author">By <span></span></div>
<!-- 播放进度 -->
<div class="progress" id="progress"></div>
</div>
<!-- 歌曲控制 -->
<div class="controls">
<div class="time" id="time">00:00</div>
<div class="play-controls">
<a href="javascript:;" class="prev btn" id="prev">
</a><a href="javascript:;" class="play btn" id="play">
</a><a href="javascript:;" class="next btn" id="next"></a>
</div>
<di

