Introduction

This sample shows the uses of mouse events on HTML5 Canvas and broadcasts the drawing to all clients using SignalR.

Tools used

  • .NET 4.5
  • SignalR
  • jQuery
  • HTML5
What SignalR is

ASP.NET SignalR is a library for ASP.NET developers that simplifies the process of adding real-time web functionality to applications. Real-time web functionality is the ability to have server code push content to connected clients instantly as it becomes available, rather than having the server wait for a client to request new data.

Output

To test the output, run the application from multiple HTML5 compatible browsers or windows.
Let us have a look to the code given below.

Step 1

Create a new project as in the following:


Step 2

Install the SignalR package from the Nuget Package console as in the following:
Step 3
Add a new class named DrawDot.cs as in the following:
DrawDot.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using Microsoft.AspNet.SignalR;
  6. namespace SignalRSample
  7. {
  8. public class DrawDot: Hub
  9. {
  10. public void UpdateCanvas(int x, int y)
  11. {
  12. Clients.All.updateDot(x, y);
  13. }
  14. public void ClearCanvas() {
  15. Clients.All.clearCanvas();
  16. }
  17. }
  18. }
Step 4
Add a new Class named Startup.cs as in the following:

Startup.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using Microsoft.Owin;
  6. using Owin;
  7. [assembly: OwinStartup(typeof(SignalRSample.Startup))]
  8. namespace SignalRSample
  9. {
  10. public class Startup
  11. {
  12. public void Configuration(IAppBuilder app)
  13. {
  14. // Any connection or hub wire up and configuration should go here
  15. app.MapSignalR();
  16. }
  17. }
  18. }
Step 5

Add a new HTML file named index.html and add the code below.

Include jQuery Script and SignalR Client JavaScript.

  • Include jQuery Script and SignalR Client JavaScript.

  • Path for dynamic ../Scripts/Hubs folder.

  • Create drawDot Hub Server connection.

  • The UpdateDot function is called from the server to update the drawing on the canvas (NOTE: In the server code, the updateDot is in camelCase like UpdateDot).

  • ClearCanvas function called by the Server to clear the canvas. (NOTE: In Server code, the clearCanvas is in camelCase like ClearCanvas).

  • OnMouseMove and OnMouseDown calls the updateCanvas Server function.
Complete index.html
  1. <!DOCTYPE html>
  2. <html
  3. xmlns="http://www.w3.org/1999/xhtml">
  4. <head>
  5. <title>SignalR Sketchpad</title>
  6. <script src="Scripts/jquery-1.6.4.min.js"></script>
  7. <script src="Scripts/jquery.signalR-2.2.0.js"></script>
  8. <script src="/signalr/hubs"></script>
  9. <script type="text/javascript">
  10. //Create the SignalR Connection
  11. var DOT = $.connection.drawDot;
  12. //Start the SignalR hub
  13. $.connection.hub.start().done();
  14. //Function called from DrawDot Server
  15. DOT.client.updateDot = function (x, y) {
  16. drawDot(x, y, 8);
  17. };
  18. //Function called from DrawDot Server
  19. DOT.client.clearCanvas = function (x, y) {
  20. clearCanvas();
  21. };
  22. //////////////////////////////////////////////////////
  23. // Variables for referencing the canvas and 2dcanvas context
  24. var canvas, ctx;
  25. // Variables to keep track of the mouse position and left-button status
  26. var mouseX, mouseY, mouseDown = 0;
  27. // Draws a dot at a specific position on the supplied canvas name
  28. // Parameters are: A canvas context, the x position, the y position, the size of the dot
  29. function drawDot(x, y, size)
  30. {
  31. // Let's use black by setting RGB values to 0, and 255 alpha (completely opaque)
  32. r = 0; g = 0; b = 0; a = 255;
  33. // Select a fill style
  34. ctx.fillStyle = "rgba(" + r + "," + g + "," + b + "," + (a / 255) + ")";
  35. // Draw a filled circle
  36. ctx.beginPath();
  37. ctx.arc(x, y, size, 0, Math.PI * 2, true);
  38. ctx.closePath();
  39. ctx.fill();
  40. }
  41. // Clear the canvas context using the canvas width and height
  42. function cleanCanvas()
  43. {
  44. clearCanvas();
  45. DOT.server.clearCanvas();
  46. }
  47. function clearCanvas()
  48. {
  49. ctx.clearRect(0, 0, canvas.width, canvas.height);
  50. }
  51. // Keep track of the mouse button being pressed and draw a dot at current location
  52. function sketchpad_mouseDown()
  53. {
  54. mouseDown = 1;
  55. drawDot(mouseX, mouseY, 8);
  56. DOT.server.updateCanvas(mouseX, mouseY);
  57. }
  58. // Keep track of the mouse button being released
  59. function sketchpad_mouseUp()
  60. {
  61. mouseDown = 0;
  62. }
  63. // Keep track of the mouse position and draw a dot if mouse button is currently pressed
  64. function sketchpad_mouseMove(e)
  65. {
  66. // Update the mouse co-ordinates when moved
  67. getMousePos(e);
  68. // Draw a dot if the mouse button is currently being pressed
  69. if (mouseDown == 1)
  70. {
  71. drawDot(mouseX, mouseY, 8);
  72. DOT.server.updateCanvas(mouseX, mouseY);
  73. }
  74. }
  75. // Get the current mouse position relative to the top-left of the canvas
  76. function getMousePos(e)
  77. {
  78. if (!e)
  79. var e = event;
  80. if (e.offsetX)
  81. {
  82. mouseX = e.offsetX;
  83. mouseY = e.offsetY;
  84. }
  85. else if (e.layerX)
  86. {
  87. mouseX = e.layerX;
  88. mouseY = e.layerY;
  89. }
  90. }
  91. // Set-up the canvas and add our event handlers after the page has loaded
  92. function init()
  93. {
  94. // Get the specific canvas element from the HTML document
  95. canvas = document.getElementById('sketchpad');
  96. // If the browser supports the canvas tag, get the 2d drawing context for this canvas
  97. if (canvas.getContext)
  98. ctx = canvas.getContext('2d');
  99. // Check that we have a valid context to draw on/with before adding event handlers
  100. if (ctx)
  101. {
  102. // React to mouse events on the canvas, and mouseup on the entire document
  103. canvas.addEventListener('mousedown', sketchpad_mouseDown, false);
  104. canvas.addEventListener('mousemove', sketchpad_mouseMove, false);
  105. window.addEventListener('mouseup', sketchpad_mouseUp, false);
  106. }
  107. else
  108. {
  109. document.write("Browser not supported!!");
  110. }
  111. }
  112. </script>
  113. <style>
  114. /* Some CSS styling */
  115. .rightside
  116. {
  117. float: left;
  118. margin-left: 10px;
  119. }
  120. #sketchpad
  121. {
  122. float: left;
  123. height: 300px;
  124. width: 400px;
  125. border: 2px solid #888;
  126. border-radius: 4px;
  127. position: relative; /* Necessary for correct mouse co-ords in Firefox */
  128. }
  129. #clear_button, #save_button
  130. {
  131. float: left;
  132. font-size: 15px;
  133. padding: 10px;
  134. -webkit-appearance: none;
  135. background: #eee;
  136. border: 1px solid #888;
  137. margin-bottom: 5px;
  138. }
  139. </style>
  140. </head>
  141. <body >
  142. <div id="sketchpadapp">
  143. <div class="rightside">
  144. <input type="submit"
  145. value="Clear Canvas" id="clear_button" />
  146. <br />
  147. <canvas id="sketchpad" height="300"
  148. width="400"></canvas>
  149. </div>
  150. </div>
  151. </body>
  152. </html>

References

Signalr