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

来源:互联网 发布:linux more怎么翻页 编辑:程序博客网 时间:2024/04/30 04:42

正式项目未开始,先先自己练手,做一个你画我猜小游戏,先上一个不完善的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属性方便全局使用//连接socketVue.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>

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

0 0
原创粉丝点击