使用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. poj 3254 Corn Fields

    http://poj.org/problem?id=3254 Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissio ...

  2. PL/SQL Developer安装详解(32位客户端免安装版)

    PL/SQL Developer是一个集成开发环境,专门开发面向Oracle数据库的应用.PL/SQL也是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL).PL/S ...

  3. Java多线程开发系列之三:线程这一辈子(线程的生命周期)

    前文中已经提到了,关于多线程的基础知识和多线程的创建.但是如果想要很好的管理多线程,一定要对线程的生命周期有一个整体概念.本节即对线程的一生进行介绍,让大家对线程的各个时段的状态有一定了解. 线程的一 ...

  4. java基础复习:final,static,以及String类

    2.final 1)为啥String是final修饰的呢? 自己答: 答案: 主要是为了“效率” 和 “安全性” 的缘故.若 String允许被继承, 由于它的高度被使用率, 可能会降低程序的性能,所 ...

  5. iOS简单动画

    知识架构 CALayer 图层类 CABasicAnimation 基础动画 CAKeyFrameAnimation 帧动画 CATransition 转场动画 CAAnimationGroup 动画 ...

  6. html标签中meta属性使用介绍

    前言 meta是html语言head区的一个辅助性标签.也许你认为这些代码可有可无.其实如果你能够用好meta标签,会给你带来意想不到的效果,meta标签的作用有:搜索引擎优化(SEO),定义页面使用 ...

  7. python学习笔记之基础一(第一天)

    1. python字符介绍 在C语言中没有字符串,只有字符 在python中的字符串hello,在C语言中是以字符数组在内存存放['h','e','l','l','o'],如果对字符串修改,则是在内存 ...

  8. Hi, there!

    Wish you a happy day~我们一起玩WEB前端!^ ^

  9. centos5安装salt-master

    本篇文档主要解决2个问题: 1. centos5通过yum安装的master版本肯定低于centos6安装的minion,所以必须升级salt-master 2. zeromq版本太低会报这个错 20 ...

  10. %----format 格式化字符串---- 生成器---- 迭代器

    %方式格式化字符串 顺序传参数 o转换8进制x转换十六进制 tp1 = "i am %s" % "alex"tp2 = "i am %s age %d ...