正式项目未开始,先先自己练手,做一个你画我猜小游戏,先上一个不完善的dome
在线地址  
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> 
现在开启多个页面,就可以同步画布,剩下的很多东西,慢慢完善。
————————————————
版权声明:本文为CSDN博主「点点悠悠」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/huaxiongbiao/article/details/70173853