Time for action – using the mouse to draw

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 = [];

Note

Note that if you give your global object variables default values it will make it easier for code editors that have an autocomplete feature to figure out what the type of the variable is and give you the appropriate suggestions.

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.

Note

For all of the methods in Canvas2D that wouldn't normally return a value we will return this so we can do function chaining.

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;
}

What just happened?

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.

What just happened?
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.238.70