首先利用vue的循环语句来绑定html中的列表元素
<div class="card-body" id="danmaku"> <li v-for="chat in chats"> {{ chat.name }}: {{ chat.content }} </li> </div>
new Vue({ el: '#danmaku', data: { chats: [ { name: "学生1", content: "233"}, { name: "学生2", content: "233"}, { name: "学生3", content: "233"}, { name: "学生4", content: "233"} ] } })
然后增加弹幕发送框,利用v-model绑定输入框
var msg = new Vue({ el: '#send', data: { message: '' } }) $('#btn-send').on('click', () => { addDanmaku('‘你’', msg.message); }) function addDanmaku(name, content) { while (chats.length >= 15) { chats.shift(); } chats.push({ name: name, content: content }) msg.message = ''; }
接着使用websocket进行所有客户端弹幕的同步
// 客户端js var socket = io('ws://' + window.location.host); socket.on('down', function(data) { addDanmaku(data.name, data.content); }) socket.emit('up', { name: name, content: msg.message });
// 服务端js // 接收弹幕 socket.on('up', (chat) => { socket.broadcast.emit('down', chat); })
最后添加利用canvas绘制弹幕的功能,学习了一下他人的思路,先对canvas创建一个弹幕对象,设置canvas的属性并创建容器,然后利用setInterval不断更新更新弹幕文本的位置,并重绘canvas。控制绘图的draw函数:
// 绘制弹幕 this.draw = function () { if (this.interval != "") return; // 如果已经有重绘,则返回 var _this = this; // 传入this(弹幕对象) this.interval = setInterval(function () { // 每20毫秒进行一次绘制 _this.ctx.clearRect(0, 0, _this.width, _this.height); // 先擦除画布 _this.ctx.save(); // 然后将当前画布保存 for (var i = 0; i < _this.msgs.length; i++) { if (!(_this.msgs[i] == null)) { if (_this.msgs[i].left==null) { // 新创建的弹幕,不存在作为左坐标left属性 _this.msgs[i].left = _this.width; // 新弹幕的位置在最右边 _this.msgs[i].top = parseInt(Math.random() * 200) + 30; // 设置弹幕的高度 _this.msgs[i].speed = 4; // 设置弹幕的速度 _this.msgs[i].color = _this.colorArr[Math.floor(Math.random() * _this.colorArr.length)]; // 设置弹幕的颜色 }else{ if(_this.msgs[i].left < -200){ _this.msgs[i]=null; // 弹幕离开屏幕后删除 }else { _this.msgs[i].left = parseInt(_this.msgs[i].left - _this.msgs[i].speed); // 弹幕移动 _this.ctx.fillStyle = _this.msgs[i].color; // 在画板上设置颜色 _this.ctx.fillText(_this.msgs[i].msg, _this.msgs[i].left, _this.msgs[i].top); // 在画板上重绘弹幕 _this.ctx.restore(); // 写入画板 } } } } }, 20); };
并且同时将创建弹幕的函数调用放在addDanmuku函数中,这样不论是自己发弹幕还是接收弹幕,都可以看见飘过的弹幕