原文地址:http://www.pwhack.me/archives/mobile-remote-presentation-controller.html
小弟最近有幸被邀请在杭电本部(我是东校区的屌丝)做了一个演讲。同学们可能对我用手机来控制ppt比较好奇,想知道究竟是如何做到的。其实非常简单,完全通过websocket来发送指令,接收指令后用reveal.js的api来实现对幻灯片的控制。impress.js也有相应的api,只要修改几行代码就好了。
之前本来想直接用remote-presentation-controller的,但是这个controller是使用express + socket.io来实现的,我认为,只是一个ppt而已,没必要弄得这么重。特别是socket.io会把html代码限制在socket.io服务器上,这样缺乏必要的灵活性,而且websocket本身就非常简单好用,没必要再用封装的东西。
由于不满意这个轮子,于是自己昨晚临时赶了一个轮子出来,仅实现最简单的控制功能,未实现安全验证等功能。
PPT端
index.html
<!-- reveal.js的ppt代码,如果你不是一个coder可以在http://slid.es上制作 -->
<script src="js/reveal.min.js"></script>
<!-- 引入我们的js -->
<script type="text/javascript" src="js/remote.js"></script>
<script>
//reveal.js初始化代码
Reveal.initialize({ ... });
</script>
remote.js
var PPT = 1;
var OP_UP = 0;
var OP_DOWN = 1;
var OP_LEFT = 2;
var OP_RIGHT = 3;
var socket = new WebSocket('ws://somewhere.com:3000');
socket.onopen = function (event) {
console.log('connection has been established.');
};
socket.onmessage = function (event) {
var data = JSON.parse(event.data);
switch (data.action) {
case OP_UP:
Reveal.navigateUp();
break;
case OP_DOWN:
Reveal.navigateDown();
break;
case OP_LEFT:
Reveal.navigateLeft();
break;
case OP_RIGHT:
Reveal.navigateRight();
break;
}
}
服务器端
server.js
这里使用了node-websocket-server,一个经典的node.js websocket服务器模块。我对其进行了必要的修改
var CONTROLLER = 0;
var ws = require(__dirname + '/lib/ws/server');
var server = ws.createServer();
server.addListener('connection', function (conn) {
console.log(conn.id + ' has connected to the server');
conn.addListener('message', function (msg) {
var data = JSON.parse(msg);
if (data.sender === CONTROLLER) {
var command = {};
command.action = data.action;
server.broadcast(JSON.stringify(command));
}
});
});
server.listen(3000);
console.log('server listening on 3000');
控制台端
这个布局参考了remote-presentation-controller中控制台的布局,并增加了指示连接状态的圆形指示灯。请原谅我由于时间仓促而使用了丑陋的<center>
,还有内嵌的css。希望这些糟糕的代码没能影响你的好心情。T.T
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no">
<title></title>
</head>
<body style="background-color: #34495e;">
<div id="operation" style="border-radius: 300px; height: 50px; width: 50px; background-color:#c0392b;"></div>
<center>
<table>
<tr>
<td></td>
<td><img class="ctl_btn up" cmd="up" src="images/arrow_up.png" /></td>
<td></td>
</tr>
<tr>
<td><img class="ctl_btn left" cmd="left" src="images/arrow_left.png" /></td>
<td></td>
<td><img class="ctl_btn right" cmd="right" src="images/arrow_right.png" /></td>
</tr>
<tr>
<td></td>
<td><img class="ctl_btn down" cmd="down" src="images/arrow_down.png" /></td>
<td></td>
</tr>
</table>
</center>
<script type="text/javascript" src="http://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.3.min.js></script>
<script type="text/javascript">
var CONTROLLER = 0;
var OP_UP = 0;
var OP_DOWN = 1;
var OP_LEFT = 2;
var OP_RIGHT = 3;
$(function () {
var socket = new WebSocket('ws://somewhere.com:3000');
socket.onopen = function () {
$('#operation').css('background-color', '#2ecc71');
};
socket.onclose = function () {
$('#operation').css('background-color', '#c0392b');
};
socket.onerror = function (event) {
console.dir(event);
};
$('.up').click(function () {
var data = {};
data.sender = CONTROLLER;
data.action = OP_UP;
console.log(JSON.stringify(data));
socket.send(JSON.stringify(data));
});
$('.down').click(function () {
var data = {};
data.sender = CONTROLLER;
data.action = OP_DOWN;
console.log(JSON.stringify(data));
socket.send(JSON.stringify(data));
});
$('.left').click(function () {
var data = {};
data.sender = CONTROLLER;
data.action = OP_LEFT;
console.log(JSON.stringify(data));
socket.send(JSON.stringify(data));
});
$('.right').click(function () {
var data = {};
data.sender = CONTROLLER;
data.action = OP_RIGHT;
console.log(JSON.stringify(data));
socket.send(JSON.stringify(data));
});
});
</script>
</body>
</html>
使用方法
- 将你包含remote.js的reveal.js演示ppt上传至任何web服务器
- 还有你的控制器html也是,上传至任何你想上传的web服务器
- 将你的server.js放在某个安装了node.js的服务器(或者你的pc也行),然后执行
node server.js
为什么这样更好
这样一来,ppt端,控制台端,服务器端,全部都分离开了,灵活性更大。
Further work if possible :-)
因为我个人以后肯定还会做各种各样的演讲,所以我打算把这个小玩意儿完善一点。
1. 重构现有的代码
2. 加入hammer.js
3. 加入访问权限控制,考虑使用二维码 + token的形式,而不是笨重的账号密码
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。