Time for action – adding an Ellipse tool

Let's use some transformations to draw an ellipse in Canvas Pad. An ellipse is basically a squashed circle. We can use the scale() method to change the scale of either the x or y axis before drawing a circle to squash it into an ellipse. Let's add a drawEllipse() method to the Canvas2D object. It takes a center point, an end point, and a Boolean to determine if it should be filled:

this.drawEllipse = function(center, endPoint, fill)
{
    var rx = Math.abs(endPoint.x - center.x);
    var ry = Math.abs(endPoint.y - center.y);
    var radius = Math.max(rx, ry);
    var scaleX = rx / radius;
    var scaleY = ry / radius;

    context.save();
    context.translate(center.x, center.y);
    context.scale(scaleX, scaleY);
    context.beginPath();
    context.arc(0, 0, radius, 0, Math.PI * 2, true);
    context.closePath();
    if (fill) context.fill();
    else context.stroke();
    context.restore();
    
    return this;
};

There's a lot going on in here, so let's break it down:

  1. First we find the horizontal and vertical radii (rx and ry) by calculating the distance between the end point and the center point coordinates. Whichever one is the largest will be the radius of the ellipse.
  2. Next we find the horizontal and vertical scales by dividing the radii by the max radius. Since one of the radii is the max radius, that scale will be 1. The other will be scaled less than 1.
  3. Next we call save() to save the state of the context before we start transforming it.
  4. Now we do our transformations. First we translate to the center of the ellipse, so it will transform around the center of the shape. Then we scale by the amounts we calculated previously.
  5. Then we draw the circle with beginPath(), arc(), and closePath(). Since the canvas is scaled on one axis, the circle will be squashed into an ellipse.
  6. Then we call either fill() or stroke() depending on the fill parameter to draw the circle to the canvas.
  7. Finally we call restore() to restore the context to the way it was before we applied the transformations, and we're done.

Now that we have a method to draw an ellipse, we can go add an Ellipse menu item to the Tool menu in our HTML:

<li data-value="ellipse">Ellipse</li>

The only thing left to do is add an option for the Ellipse tool in the switch statement in redraw() and we're done:

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

What just happened?

We added an Ellipse tool to our application and implemented a method to draw an ellipse on the canvas using transformations to squash a circle on one axis.

..................Content has been hidden....................

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