Node学习笔记(三):基于socket.io web版你画我猜(一)
经过惨淡的面试,也是知道了自己的不足,刚好最近在学习node,心中便有了做一个web版的你画我猜的想法
首先说下思路,在做准备工作的时候,有两个大概的思路:
1.规定一块div,捕捉鼠标事件,动态生成position absolute,长宽1px的红色小div,这样可以模拟出划线的轨迹,做一个long polling,不断获取DOM结构,推送到socket端口,然后再广播给所有客户端
2.利用canvas作图,将canvas的数据推送到socket端口,广播所有客户端
其实之所以有两种想法,无非就是作图这块出现了分歧,方法一,大量DOM树的重绘,无疑会给浏览器造成巨大的负担,但是canvas作图,也苦于数据无法导出,但是功夫不负有心人,canvas的数据流是可以通过toDataURL()导出数据的,于是开动!
var paint=false;//判断是否是需要绘画 var container=document.getElementById('container') var context=container.getContext("2d") var mouseX=0,mouseY=0,nowX=0,nowY=0;//存储坐标记录
做一个对象对事件进行汇总,包含对position的替换重置,canvas的绘制及重绘,导出数据
var position={ reset:function(actionX,actionY,goalX,goalY){ //坐标替换 paint=true; var order=" "+actionX+"="+goalX+","+actionY+"="+goalY; eval(order); console.log(mouseX); }, init:function(){ //坐标清零 console.log("init"); paint=false; mouseX=0; mouseY=0; nowX=0; noxY=0; } } var canvas={ init:function(){ //canvas初始化 context.strokeStyle = "blue"; context.strokeRect(0,0,300,200); context.stroke(); }, draw:function(lastX,lastY,nowX,nowY){ //canvas划线 context.lineWidth = 1; context.beginPath(); context.moveTo(lastX, lastY); context.lineTo(nowX,nowY); context.stroke(); position.reset('mouseX','mouseY',nowX,nowY); }, redraw:function(){ //canvas重绘 position.init(); }, returnData:function(){ //canvas导出数据流 socket.emit('startConnect', container.toDataURL()) } }
绘图最重要的就是对坐标的处理,我们在鼠标点击的时候记录点击时的坐标,存储起来付给mouseXY,在mousemove的时候记录坐标付给NowXY,用lineto进行绘线,鼠标点击弹起时,paint置为false 停止绘画
$("#container").mousedown(function(e){ position.reset('mouseX','mouseY',e.pageX-this.offsetLeft,e.pageY-this.offsetTop); console.log(mouseX+":"+mouseY); }) $("#container").mousemove(function(e){ if(paint){ console.log(mouseX+":"+mouseY); position.reset('nowX','nowY',e.pageX-this.offsetLeft,e.pageY-this.offsetTop); canvas.draw(mouseX,mouseY,nowX,nowY); } }) $("#container").mouseup(function(e){ if(paint){ position.init(); canvas.returnData(); } }) $("#container").mouseleave(function(e){ if(paint){ position.init(); } })
效果如图
ok,绘图就算解决了,下面要解决的就是客户端的管理与同步了