zoukankan      html  css  js  c++  java
  • 用SignalR实现的共享画板例子

    使用HTML5的canvas画布功能,在页面进行绘画,然后通过SignalR将画布的每个点的颜色提交到服务端,服务端同时将这些画布的信息推送到其他客户端,实现共享同一个画板的功能

    类似下图,在某一个浏览器进行绘画,其他浏览器同步显示内容,并且页面刷新或者首次加载还能显示之前的绘画内容(站点不重启的情况下)

    image

    实现过程

    一、服务端

    服务端的代码主要功能是接收客户端发送过来的绘画坐标点和坐标点的颜色,同时将新的坐标点信息推送给客户端,最后服务端还会保存这些绘画坐标点信息到内存中,这样客户端刷新或者首次进入就能看到之前的绘画信息。

    step1:

    创建一个Empty类型的ASP.NET 4.5的站点

    image

    step2:

    引入SignalR的nuget包,将自动引入相关的关联包

    Install-Package Microsoft.AspNet.SignalR

    step3:

    新建一个SignalR Hub Class

    实现代码如下:

    public class DrawingBoard : Hub 
        { 
            private const int BoardWidth = 300; 
            private const int BoardHeight = 300; 
            private static int[,] _pointBuffer = GetEmptyPointBuffer();
    
            public Task DrawPoint(int x, int y) 
            { 
                if (x < 0) 
                { 
                    x = 0; 
                } 
                if (x >= BoardWidth) 
                { 
                    x = BoardWidth - 1; 
                } 
                if (y <0) 
                { 
                    y = 0; 
                } 
                if (y >= BoardHeight) 
                { 
                    y = BoardHeight - 1; 
                } 
                int color = 0; 
                int.TryParse(Clients.Caller.color, out color); 
                _pointBuffer[x, y] = color; 
                return Clients.Others.drawPoint(x, y, Clients.Caller.color); 
            }
    
            public Task Clear() 
            { 
                _pointBuffer = GetEmptyPointBuffer(); 
                return Clients.Others.clear(); 
            }
    
            public override Task OnConnected() 
            { 
                return Clients.Caller.update(_pointBuffer); 
            }
    
            private static int[,] GetEmptyPointBuffer() 
            { 
                var buffer = new int[BoardWidth, BoardWidth]; 
                return buffer; 
            } 
        }
    View Code

    step4:

    新建一个startup类

    public class Startup 
        { 
            public void Configuration(IAppBuilder app) 
            { 
                app.MapSignalR(); 
            } 
        }
    Startup

    到此完成服务端的功能实现

    二、客户端

    step1:

    客户端的html页面只需要定义一个canvas元素和一个清除画布的按钮

    <!DOCTYPE html> 
    <html> 
    <head> 
        <title>在线画板</title> 
        <meta charset="utf-8" /> 
        <style> 
            div{ 
                margin:3px; 
            } 
            canvas{ 
                border:2px solid #808080; 
                cursor:default; 
            } 
        </style> 
    </head> 
    <body> 
        <div> 
            <div> 
                <label for="color">Color:</label> 
                <select id="color"></select> 
            </div> 
            <canvas id="canvas" width="300" height="300"></canvas> 
            <div> 
                <button id="clear">Clear canvas</button> 
            </div> 
        </div> 
        <script src="/Scripts/jquery-1.6.4.min.js"></script> 
        <script src="/Scripts/jquery.signalR-2.2.0.min.js"></script> 
        <script src="/signalr/js"></script> 
        <script src="/Scripts/drawingboard.js"></script> 
    </body> 
    </html>
    Html

    step2:

    在scripts目录创建drawingboard.js文件,实现主要的画布操作和SingalR事件绑定。

    主要是绑定了canvas的mousemove事件,然后再mousemove事件中实现绘画,同时将绘画的信息发送服务器,客户端同时接收服务端推送的绘画信息,实时提现在本地的画布中。

    客户端连接成功之后,会获得从服务端推送的历史绘画信息,实现记载之前画布的效果

    $(function () { 
        // 画布定义开始 
        var colors = ["black", "red", "green", "blue", "yellow", "magenta", "white"]; 
        var canvas = $("#canvas"); 
        var colorElement = $("#color"); 
        for (var i = 0; i < colors.length; i++) { 
            colorElement.append("<option value='" + (i + 1) + "'>" + colors[i] + "</option>"); 
        } 
        var buttonPressed = false; 
        canvas 
            .mousedown(function () { 
                buttonPressed = true; 
            }) 
            .mouseup(function () { 
                buttonPressed = false; 
            }) 
            .mousemove(function (e) { 
                if (buttonPressed) { 
                    setPoint(e.offsetX, e.offsetY, colorElement.val()); 
                } 
            });
    
        var ctx = canvas[0].getContext("2d"); 
        function setPoint(x, y, color) { 
            ctx.fillStyle = colors[color - 1]; 
            ctx.beginPath(); 
            ctx.arc(x, y, 2, 0, Math.PI * 2); 
            ctx.fill(); 
        } 
        function clearPoints() { 
            ctx.clearRect(0, 0, canvas.width(), canvas.height()); 
        }
    
        $("#clear").click(function () { 
            clearPoints(); 
        }); 
        // 画布定义结束
    
        // SignalR 客户端代码 
        var hub = $.connection.drawingBoard; 
        hub.state.color = colorElement.val(); 
        var connected = false;
    
        colorElement.change(function () { 
            hub.state.color = $(this).val(); 
        });
    
        canvas.mousemove(function (e) { 
            if (buttonPressed && connected) { 
                hub.server.drawPoint(Math.round(e.offsetX), Math.round(e.offsetY)); 
            } 
        });
    
        $("#clear").click(function () { 
            if (connected) { 
                hub.server.clear(); 
            } 
        });
    
        // 定义客户端方法 
        hub.client.clear = function () { 
            clearPoints(); 
        };
    
        hub.client.drawPoint = function (x, y, color) { 
            setPoint(x, y, color); 
        };
    
        hub.client.update = function (points) { 
            if (!points) return; 
            var width = canvas.width(); 
            var height = canvas.height(); 
            for (var x = 0; x < width; x++) { 
                for (var y = 0; y < height; y++) { 
                    var color = points[x][y]; 
                    if (color > 0) { 
                        setPoint(x, y, color); 
                    } 
                } 
            } 
        };
    
        $.connection.hub.start().done(function () { 
            connected = true; 
        }); 
    })
    drawingBoard

    完整代码下载

  • 相关阅读:
    spring mvc 总结
    linux安装tomcat及优化
    mysql支持emoji表情
    面试问题
    linux安装jdk mysql
    webstorm 介绍
    spring 总结
    UML工具
    js bom dom
    awt多线程聊天
  • 原文地址:https://www.cnblogs.com/shenba/p/5417794.html
Copyright © 2011-2022 走看看