The first thing we need to do is capture mouse events. Let's go into our CanvasPadApp
object and add the code to check for them in the start()
method. As you may recall, we already added a mousemove
event handler above. Now we will add handlers for mousedown
, mouseup
, and mouseout
events:
$("#main>canvas").mousemove(onMouseMove) .mousedown(onMouseDown) .mouseup(onMouseUp) .mouseout(onMouseUp);
No, there's not a mistake in mouseout
. We want the mouseout
event to be handled the same way as mouseup
, so they both stop the drawing process. The mouseout
event is fired when the mouse leaves the <canvas>
element. When that happens we can't get mousemove
events anymore and therefore lose track of the pen position.
Before we implement the event handlers we need a couple of new variables to keep track of things. We need a Boolean value to keep track of when we are drawing, an array to keep track of the current set of points, and an array to keep track of all the sets of points (we will call them actions):
var version = "4.1", canvas2d = new Canvas2D($("#main>canvas")), drawing = false, points = [], actions = [];
First let's implement onMouseDown()
since this starts the drawing process. It takes one parameter, which is the mouse event object:
function onMouseDown(e) { e.preventDefault(); penDown(e.pageX, e.pageY); } function penDown(pageX, pageY) { drawing = true; points = []; points.push(canvas2d.getCanvasPoint(pageX, pageY)); actions.push(points); }
The first thing we do in the onMouseDown()
method is call preventDefault()
on the mouse event object. This will stop the system from doing the default mouse down behavior, part of which is to change the mouse cursor icon. We want it to remain a cross icon, which we previously set in the CSS. Then we call penDown()
passing in the page coordinates of the mouse which we get from the mouse event.
In the penDown()
method we initialize the drawing process. First, we set the drawing
flag to true
. Then we create a new array to put the current drawing points into it. Then we add the first point to the array after converting it from page coordinates to canvas coordinates by calling getCanvasPoint()
. The final thing we do is add the current points
array to the actions
array.
The next step in the drawing process is to handle mousemove
events, so let's rewrite the
onMouseMove()
method:
function onMouseMove(e) { penMoved(e.pageX, e.pageY); } function penMoved(pageX, pageY) { var canvasPoint = canvas2d.getCanvasPoint(pageX, pageY); showCoordinates(canvasPoint); if (drawing) { points.push(canvasPoint); redraw(); } }
Now onMouseMove()
calls penMoved()
passing it the mouse coordinates. The penMoved()
method first converts the coordinates then calls showCoordinates()
as it did before. Then we check if the drawing
flag is set. This was set in the penDown()
method so we know that the mouse button is down. If the user is drawing then we add the current point to the array of points and call redraw()
, which we will implement next:
function redraw() { canvas2d.clear(); for (var i in actions) { canvas2d.drawPoints(actions[i]); } }
The redraw()
method first clears the canvas by calling canvas2d.clear()
, which we will write next, then it iterates over all of the actions and calls drawPoints()
passing in the set of points for each action.
Now let's go into our Canvas2D
object and add the clear()
and drawPoints()
methods. First, our clear()
method calls the context.clearRect()
method passing in the canvas width
and height
variables we defined in the Canvas2D
constructor:
this.clear = function() { context.clearRect(0, 0, width, height); return this; };
Next, the drawPoints()
method takes an array of points and draws lines between them:
this.drawPoints = function(points) { context.beginPath(); context.moveTo(points[0].x, points[0].y); for (var i = 1; i < points.length; i++) { context.lineTo(points[i].x, points[i].y); } context.stroke(); return this; };
After beginning a new path it calls moveTo()
to move the pen to the first point in the array. Then it iterates over the remaining points in the array calling lineTo()
for each one. When it's done it calls stroke()
to draw it to the canvas.
The last thing we need to implement is the onMouseUp()
event handler. All we need to do here is set the drawing
flag back to false
:
function onMouseUp(e) { penUp(); } function penUp() { drawing = false; }
We used mouse events to capture and store drawing actions in a buffer. Then we used the canvas API to draw lines to the canvas from those points. Now let's open our application in the browser and check it out. We can scribble on the canvas using the mouse and create simple line drawings.
3.147.238.70