zoukankan      html  css  js  c++  java
  • socket + vue + canvas实践,你画我猜(一)

    正式项目未开始,先先自己练手,做一个你画我猜小游戏,先上一个不完善的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="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;
    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{
    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;
    100%;
    overflow-x: hidden;
    overflow-y: auto;
    }
    </style> 
    现在开启多个页面,就可以同步画布,剩下的很多东西,慢慢完善。


    ————————————————
    版权声明:本文为CSDN博主「点点悠悠」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/huaxiongbiao/article/details/70173853

  • 相关阅读:
    Centos7下安装pip
    Docker进入容器后使用ifconfig等命令“command not found”解决办法
    安装包安装npm
    grafna与饼状图
    Postgresql导出数据报版本不对
    添加动物欢迎语
    zabbix性能优化记
    CPU使用情况之平均负载
    centos7以rpm方法装mysql5.7及大坑
    光速搭lvs + keepalived + nginx
  • 原文地址:https://www.cnblogs.com/javalinux/p/14768937.html
Copyright © 2011-2022 走看看