socket + vue + canvas实践,你画我猜(一)

    xiaoxiao2021-04-19  186

    正式项目未开始,先先自己练手,做一个你画我猜小游戏,先上一个不完善的dome

    在线地址 http://www.5rgame.com 1.node; 安装socket,启动服务

    var io = require('socket.io').listen(server); var messages = [];//暂时存放消息 //socket连接成功之后触发,用于初始化 io.sockets.on('connection', function(socket){ socket.on('getAllMessages', function(){ //用户连上后,发送messages socket.emit('allMessages', messages); }); socket.on('createMessage', function(message){ //用户向服务器发送消息,存放到messages //messages.push(message); //向除自己外的所有用户发送消息 socket.broadcast.emit('messageAdded', message); }); })

    2.vue 设置;先在index.html直接引入socket.io.js,此文件由node生成;

    <script type='text/javascript' src='http://localhost:3000/socket.io/socket.io.js' charset='utf-8'></script> //然后在vue对象上新增socket属性方便全局使用 //连接socket Vue.prototype.socket = io.connect('http://localhost:3000/');

    3.vue文件的画图与数据传输交互

    <template> <div id="gameRoom"> <header class="mui-bar mui-bar-nav"> <a class="mui-icon mui-icon-arrowleft Hui-icon-left" v-on:tap="back()"></a> <h1 class="mui-title Hui-title"><p class="ellipsis">房间名字</p><i class="ellipsis">你画我猜</i></h1> <a class="Hui-icon-right mui-icon-extra mui-icon-extra-peoples Hui-icon"></a> </header> <nav class="mui-bar mui-bar-tab Hui-chat-bar" style="height:auto"> <div class="sentNews"> <a href="javascript:;"><i class="mui-icon mui-icon-mic"></i></a> <div contenteditable="true"></div> <a href="javascript:;"><i class="Hui-icon Hui-icon-face"></i></a> <a href="javascript:;"><i class="mui-icon mui-icon-plus"></i></a> </div> <div style="width:100%;height:200px;display:none"></div> </nav> <div class="gameRoom-canvas"> <div class="canvas-bar"><span>1号正在画,请先围观~{{screenHeight}}</span><span>剩余时间:<i>60</i></span></div> <canvas id="gameCanvas" v-bind:width="screenWidth" v-bind:height="screenHeight" v-on:touchstart="touchStart($event)" v-on:touchmove="touchMove($event)" v-on:touchcancel="touchCancel($event)" v-on:touchend="touchEnd($event)" v-on:touchleave="touchEnd($event)"></canvas> </div> <div id="chat-scroll" class="mui-content Hui-chat-scroll" v-bind:style="{top:screenHeight+68+'px'}"> <input type="color" value="#333333" list="colors"> <datalist id="colors"> <option>#ffffff</option> <option>#ff0000</option> <option>#ff7700</option> </datalist> <input type="range" name="points" min="1" max="10" /> </div> </div> </template> <script> export default{ data(){ return { screenHeight: '', screenWidth: '', canvasGo:'', messages:[], dom:false } }, mounted(){ var that = this; this.canvasGo = new operatCanvas(); this.screenWidth = document.body.clientWidth; this.screenHeight = this.screenWidth*(3/5); //接收消息 this.socket.on('messageAdded', function(message){ if(that.dom){ that.canvasGo.drawCanvas(message.parameter,message.opt,message.Start); }else{ that.messages.push(message); } }); //页面大小改变 window.onresize = function(){ that.screenWidth = document.body.clientWidth; that.screenHeight = that.screenWidth*(3/5); } }, methods:{ back(){ this.$router.go(-1); }, updateMessage: function () { this.$nextTick(function () {//当值变化dom更新完成 this.dom = true; if(this.messages.length>0){ for(let i=0; i<this.messages.length; i++){ this.canvasGo.drawCanvas(message[i].parameter,message[i].opt,message[i].Start); } } }) }, send:function(message){ //发送消息 this.socket.emit('createMessage',message); }, touchStart:function(event){ let that = this; this.canvasGo.handleStart(event,function(message){ that.send(message); }); }, touchMove:function(event){ let that = this; this.canvasGo.handleMove(event,function(message){ that.send(message); }); }, touchCancel:function(event){ this.canvasGo.handleCancel(event); }, touchEnd:function(event){ let that = this; this.canvasGo.handleEnd(event,function(message){ that.send(message); }); } }, watch:{      screenHeight:'updateMessage'//当值变化时触发   } } //获取坐标点与颜色画笔类型 function operatCanvas(){ var gameCanvas = document.getElementById("gameCanvas"); var ctx=gameCanvas.getContext("2d"); var touchAggregate = new Array(); var that = this; var _default = { color: '#333', //画笔颜色 lineWidth: 3, //画笔大小 lineCap: 'round', //绘制圆形的结束线帽 ,可选值:square lineJoin: 'round' //当两条线条交汇时,创建圆形边角 }; var ongoingTouchIndexById = function(idToFind){ for (let i=0; i<touchAggregate.length; i++) { let id = touchAggregate[i].identifier; if (id == idToFind) { return i; } } return -1; // not found } this.handleStart = function(event,callback){ event.preventDefault(); var touches = event.changedTouches;//获取正在发生此事件的 var Start = true; for(let i=0; i<touches.length; i++){ touchAggregate.push(touches[i]); let opt = { x:touches[i].pageX, y:touches[i].pageY } that.drawCanvas(_default,opt,Start); that.back(_default,opt,Start,callback); } }; this.handleMove = function(event,callback){ event.preventDefault(); var touches = event.changedTouches;//获取正在发生此事件的 for(let i=0; i<touches.length; i++){ let idx = ongoingTouchIndexById(touches[i].identifier); let opt = { x:touches[i].pageX, y:touches[i].pageY, sx:touchAggregate[idx].pageX, sy:touchAggregate[idx].pageY } that.drawCanvas(_default,opt); touchAggregate.splice(idx, 1, touches[i]); that.back(_default,opt,false,callback); } }; this.handleEnd = function(event,callback){ event.preventDefault(); var touches = event.changedTouches; for (let i=0; i<touches.length; i++) { let idx = ongoingTouchIndexById(touches[i].identifier); let opt = { x:touches[i].pageX, y:touches[i].pageY, sx:touchAggregate[idx].pageX, sy:touchAggregate[idx].pageY } that.drawCanvas(_default,opt); touchAggregate.splice(i, 1); // remove it; we're done that.back(_default,opt,false,callback); } }; this.handleCancel = function(event) { evt.preventDefault(); var touches = evt.changedTouches; for (let i=0; i<touches.length; i++) { touchAggregate.splice(i, 1); // remove it; we're done } } this.drawCanvas = function(_default,opt,Start){ ctx.lineWidth = _default.lineWidth; ctx.strokeStyle = _default.color; ctx.lineCap = _default.lineCap; ctx.lineJoin = _default.lineJoin; if(Start){ ctx.beginPath(); ctx.moveTo(opt.x-1, opt.y-69); ctx.lineTo(opt.x, opt.y-68); ctx.closePath(); ctx.stroke(); }else{ ctx.beginPath(); ctx.moveTo(opt.sx, opt.sy-68); ctx.lineTo(opt.x, opt.y-68); ctx.closePath(); ctx.stroke(); } } this.back = function(_default,opt,Start,callback){ var message = { parameter: _default, opt: opt, Start: Start }; callback(message); } } </script> <style lang="less" scoped> @bg-default:#cd3d3d; @color-default:#cd3d3d; @text-color:#f67575; .gameRoom-canvas{ position: absolute; top: 44px; left: 0; width: 100%; background: #fff; z-index: 99; .canvas-bar{ color: #fff; background: #999; font-size: 12px; padding: 2px 10px; line-height: 20px; overflow: hidden; >span:last-child{ float: right; color: #f5ef3c; } } #gameCanvas{ background: #fff; display: block; } } #app{ .mui-bar.mui-bar-nav{ box-shadow: none; .Hui-icon-left{ font-size: 34px; padding: 5px 0; margin: 0; position: absolute; top: 0; left: 0; } .Hui-icon-right{ display: block; color: #fff; position: absolute; top: 0; right: 10px; padding: 5px 0; font-size: 26px; line-height: 34px; } .Hui-title{ line-height: 20px; >p{ font-size: 16px; line-height: 22px; padding-top: 5px; color: #fff; } >i{ display: block; font-size: 12px; font-weight: 400; line-height: 14px; } } } .Hui-chat-bar{ background: #fffcfc; border: none; box-shadow: none; border-top: #E8E8E8 1px solid; box-sizing: content-box; z-index: 9998; .mui-icon{ color: #666; } i.Hui-icon-face{ background: url(../../assets/images/icon2.png) no-repeat center; background-size: 100%; } } } .sentNews{ display: flex; overflow: hidden; align-items:flex-end; height: 50px; >div{ flex-grow: 1; line-height: 18px; padding: 8px 3px 2px 3px; font-size: 14px; word-break:break-all; word-wrap:break-word; margin-bottom: 12px; border-bottom: #ddd 1px solid; } >a{ padding: 0 5px; height: 50px; flex-grow: 0; flex-shrink: 0; >i.mui-icon{ font-size: 30px; padding-top: 10px; padding-bottom: 5px; vertical-align: bottom; } >i.Hui-icon{ width: 30px; height: 30px; background-size: 24px; margin-top: 10px; } } >a:nth-of-type(2){ padding-right: 0; } >a:last-child{ padding-right: 10px; } } #chat-scroll{ background: #F5F5F5; } .Hui-chat-scroll{ position: fixed; top: 400px; bottom: 61px; padding: 0 !important; z-index: 10; left: 0; width: 100%; overflow-x: hidden; overflow-y: auto; } </style>

    现在开启多个页面,就可以同步画布,剩下的很多东西,慢慢完善。

    转载请注明原文地址: https://ju.6miu.com/read-676277.html

    最新回复(0)