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

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

实现过程

一、服务端

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

step1:

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

step2:

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

Install-Package Microsoft.AspNet.SignalR

step3:

新建一个SignalR Hub Class

实现代码如下:

public class DrawingBoard : Hub
{
private const int BoardWidth = ;
private const int BoardHeight = ;
private static int[,] _pointBuffer = GetEmptyPointBuffer(); public Task DrawPoint(int x, int y)
{
if (x < )
{
x = ;
}
if (x >= BoardWidth)
{
x = BoardWidth - ;
}
if (y <)
{
y = ;
}
if (y >= BoardHeight)
{
y = BoardHeight - ;
}
int color = ;
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;
}
}

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

完整代码下载

用SignalR实现的共享画板例子的更多相关文章

  1. [置顶] MVC中使用signalR入门教程

    一.前言:每次写总要说一点最近的感想 进入工作快半年了,昨天是最郁闷的一天,我怀疑我是不是得了"星期一综合征",每个星期一很没有状态.全身都有点酸痛,这个可能一个星期只有周末才打一 ...

  2. OpenMP共享内存并行编程详解

    实验平台:win7, VS2010 1. 介绍 平行计算机可以简单分为共享内存和分布式内存,共享内存就是多个核心共享一个内存,目前的PC就是这类(不管是只有一个多核CPU还是可以插多个CPU,它们都有 ...

  3. http与websocket(基于SignalR)两种协议下的跨域基于ASP.NET MVC--竹子整理

    这段时间,项目涉及到移动端,这就不可避免的涉及到了跨域的问题.这是本人第一次接触跨域,有些地方的配置是有点麻烦,导致一开始的不顺. 至于websocket具体是什么意义,用途如何:请百度. 简单说就是 ...

  4. SAP内存/ABAP内存/共享内存区别

    (1).读取和使用方法不同SAP内存使用SET/GET parameters方法:SET PARAMETER ID 'MAT' field p_matnr.GET PARAMETER ID 'MAT' ...

  5. 【转】七个例子帮你更好地理解 CPU 缓存

    我的大多数读者都知道缓存是一种快速.小型.存储最近已访问的内存的地方.这个描述相当准确,但是深入处理器缓存如何工作的"枯燥"细节,会对尝试理解程序性能有很大帮助. 在这篇博文中,我 ...

  6. 读书笔记-----Java并发编程实战(二)对象的共享

    public class NoVisibility{ private static boolean ready; private static int number; private static c ...

  7. 转:Spring-session & redis 子域名共享session

    Spring-session & redis 子域名共享session 例子: a.example.com b.example.com spring 版本 4.2.6.RELEASE Spri ...

  8. .net core 使用SignalR实现实时通信

    这几天在研究SignalR,网上大部分的例子都是聊天室,我的需求是把服务端的信息发送给前端展示.并且需要实现单个用户推送. 用户登录我用的是ClaimsIdentity,这里就不多解释,如果不是很了解 ...

  9. pipeline 共享库

    目录 一.简介 二.共享库扩展 共享库使用 共享库结构 pipeline模板 一些小问题 三.共享库例子 使用公共变量 使用共享库的src方法 使用共享库的vars方法 四.插件实现pipeline ...

随机推荐

  1. WPF显示Html

    1.添加引用 WindowsFormsIntegration.dll System.Windows.Forms.dll 2.界面内容 <UserControl x:Class="HKD ...

  2. redmine常见问题

    1.测试Pop3邮件收件任务:rake redmine:email:receive_pop3 RAILS_ENV="production" host=pop.cecgw.cn po ...

  3. Easy Tag Write(3.3)

    package skyseraph.android.util; /** * @Title : Constant.java * @Package : tcl.nfc.tv.util * @ClassNa ...

  4. Centos下设置VNC为3389端口

    1.安装vnc yum install vnc vnc-server yum install vnc vnc-server 2.修改vnc端口,修改/usr/bin/vncserver ,把5900变 ...

  5. final发布视频

    final版本发布的视频已上传至秒拍,视频地址: http://m.miaopai.com/show/channel/AHqv~VA7lrk144ONLWrveQ__ 以下是功能截图:         ...

  6. MVC中使用EF增删改查,简单的例子

    //这个是分页数据和总页数类 public class SummaryBase<TModel> { public SummaryBase(); public IList<TModel ...

  7. 未能加载文件或程序集“projectname, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。系统找不到指定的文件。

  8. BabelMap 9.0.0.3 汉化版(2016年12月27日更新)

    软件简介 BabelMap 是一个免费的字体映射表工具,可辅助使用<汉字速查>程序. 该软件可使用系统上安装的所有字体浏览 Unicode 中的十万个字符,还带有拼音及部首检字法,适合文献 ...

  9. Spring学习笔记之一----基于XML的Spring IOC配置

    1. 在spring配置文件中,如果对一个property进行直接赋值,可使用<value>元素,spring负责将值转化为property指定的类型:也可以直接在property元素上使 ...

  10. qt qml ajax 获取 json 天气数据示例

    依赖ajax.js类库,以下代码很简单的实现了获取天气json数据并展示的任务 [TestAjax.qml] import QtQuick 2.0 import "ajax.js" ...