Time for action – adding a rectangle tool

Let's add a tool to draw rectangles. We'll start by adding a menu item to the Tool drop-down menu with its data-value attribute set to "rect":

<li data-value="rect">Rectangle</li>

Let's implement the drawRect() method in Canvas2D:

this.drawRect = function(point1, point2, fill)
{
    var w = point2.x - point1.x,
        h = point2.y - point1.y;
    if (fill) context.fillRect(point1.x, point1.y, w, h);
    else context.strokeRect(point1.x, point1.y, w, h);
    return this;
};

Our drawRect() method takes three parameters; the two points that define top-left and bottom-right coordinates, and a Boolean value to determine if the rectangle should be filled. Since fillRect() and strokeRect() both take width and height parameters we need to compute them by subtracting the point1 variable's coordinates from point2 variable's coordinates.

Before we code up the call to drawRect() there is one piece of business we need to take care of. Our drawRect() method can draw either outlined or filled rectangles, so we need a way to let the user pick which one they want. Let's add another drop-down menu to the toolbar named Fill that allows the user to set this option:

<div class="dropdown-menu">
  <button data-action="menu">Fill</button>
    <ul data-option="fillShapes" class="menu">
      <li data-value="true" class="selected">Yes</li>
      <li data-value="false">No</li>
    </ul>
</div>

The drop-down menu has only two options: Yes and No. In our CanvasPadApp object we need a global fillShapes Boolean variable to keep track of the current setting. Let's add this at the top of the object along with our other variables:

var version = "4.3",
    // code not shown...
  fillShapes = true;

We also need to add it to the action object in the newAction() method. We will add a field named fill and set it to the current value of fillShapes:

function newAction(tool)
{
    return {
        tool: tool,
        color: canvas2d.penColor(),
        width: canvas2d.penWidth(),
        opacity: canvas2d.penOpacity(),
        fill: fillShapes,
        points: []
    };
  }

Next we need to add some extra code to the menuItemClicked() method to check if the option was the Fill menu option and if so set the fillShapes variable to its data-value. Since the value is either "true" or "false" we can convert it directly to a Boolean:

function menuItemClicked(option, value)
{
    switch (option)
    {
        case "drawingTool":
            curTool = value;
            break;
        case "fillShapes":
            fillShapes = Boolean(value);
            break;
        default:
            canvas2d[option](value);
    }
}

Okay, that's it for the Fill option. Now we can add the code to the redraw() method to check for the rectangle tool and draw it by calling drawRect(). We will pass in the two points of the rectangle and the value of action.fill to tell it whether to fill the rectangle or not:

switch (action.tool)
{
    // code not shown...
    case "rect":
        canvas2d.drawRect(action.points[0],
            action.points[1],
            action.fill);
        break;
}

What just happened?

We added a rectangle tool to our Tool menu. We also added a new toolbar menu to select whether to fill shapes or not. We used this to determine whether to draw filled or outlined rectangles.

Arcs and circles

In addition to straight lines you can draw arcs, or portions of a circle, using the context's arc() method. It takes the following parameters:

arc(centerX, centerY, radius, startAngle, endAngle, clockwise)
  • centerX: This parameter tells the horizontal position of the center point.
  • centerY: This parameter tells the vertical position of the center point.
  • radius: This parameter tells the radius of the arc.
  • startAngle: This parameter tells the starting angle of the arc specified in radians. It can be any value between 0 to . Numbers outside this range will automatically be normalized into it.
  • endAngle: This parameter tells the ending angle of the arc specified in radians. It can be any value between 0 to .
  • counterclockwise: This is a Boolean parameter that specifies which direction to draw the arc from start to end angle. If false it draws clockwise, if true counterclockwise.

Arcs are really paths, so you must use beginPath() and stroke() to draw them. The following code draws the bottom-right corner of a circle. The center is at the point (100, 200). It has a radius of 40. The angle starts at 0 and ends at π/2 radians, or 90 degrees. And it is drawn clockwise:

context.beginPath();
context.arc(100, 200, 40, 0, Math.PI / 2, false);
context.stroke();

You can draw a full circle using the arc() method too. A circle is simply a complete arc drawn from 0 to radians, or 360 degrees:

context.beginPath();
context.arc(100, 200, 40, 0, 2 * Math.PI, false);
context.stroke();

If you are unfamiliar with radians, let me give you a brief overview. Radians are simply another way to specify an angle. It is based on the formula for the circumference of a circle; C = 2 * π * radius. By setting the radius to 1, we can use that formula to measure the length of an arc from one point on the circle to another point along the circumference. If you were to measure all the way around a circle you would have radians. Therefore, radians are equal to 360 degrees. Half way around the circle is π radians, which is equal to 180 degrees. One quarter of the way around is π/2 radians or 90 degrees.

Arcs and circles

If you prefer to use degrees you can always use this conversion function to convert degrees to radians:

function toRadians(deg)
{
    return deg * Math.PI / 180;
}

Here are some examples of arcs using different parameters. Arcs 1 and 2 use the same start and end angles, just drawing in different direction. The same is true for arcs 3 and 4. Arc 5 draws a complete circle:

  • context.arc(100, 200, 40, 0, toRadians(90), true);
  • context.arc(200, 200, 40, 0, toRadians(90), false);
  • context.arc(300, 200, 40, 0, toRadians(180), true);
  • context.arc(400, 200, 40, 0, toRadians(180), false);
  • context.arc(500, 200, 40, 0, toRadians(360), false);
Arcs and circles
..................Content has been hidden....................

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