How to draw a rectangle with rounded corners

by Elis Frugalo.

Share
|
Homepage | Submit your article | Contact | TOS
More articles on flash  

You are here: Categories » Computers and technology » Flash

You want to draw a rectangle with rounded corners, an offset, or rotation.Create a custom MovieClip.drawRectangle( ) method using the Drawing API and invoke it on a movie clip.

The drawSimpleRectangle( ) method is, as the name suggests, quite simple. Let's create a more complex version that also:

  • Draws a rectangle with a specified angle of rotation
  • Let's you specify the rectangle center's coordinates
  • Can draw a rectangle with rounded corners

The drawRectangle( ) method accepts six parameters:

width
The width of the rectangle in pixels

height
The height of the rectangle in pixels

round
The radius (in pixels) of the arc that is used to round the corners. If the value is undefined or 0, the corners remain square.

rotation
The clockwise rotation to apply to the rectangle in degrees. If undefined, the rectangle is not rotated.

x
The x coordinate of the center point for the rectangle. If undefined, the rectangle is centered at x = 0.

y
The y coordinate of the center point for the rectangle. If undefined, the rectangle is centered at y = 0.

Here is our enhanced drawRectangle( ) method, defined on MovieClip.prototype, so it's available to all movie clip instances:

// Include the custom Math library to access Math.degToRad(  ).
   #include "Math.as"
MovieClip.prototype.drawRectangle = function (width, height, round, rotation, x, y) {
   // Make sure the rectangle is at least as wide and tall as the rounded corners.
   if (width < (round * 2)) {
   width = round * 2;
   }
   if (height < (round * 2)) {
   height = round * 2;
   }
 // Convert the rotation from degrees to radians.
   rotation = Math.degToRad(rotation);
 // Calculate the distance from the rectangle's center to one of the corners (or
   // where the corner would be in rounded-cornered rectangles).
   var r = Math.sqrt(Math.pow(width/2, 2) + Math.pow(height/2, 2));
 // Calculate the distance from the rectangle's center to the upper edge of the
   // bottom-right rounded corner. When round
   // is 0, rx is equal to r.
   var rx = Math.sqrt(Math.pow(width/2, 2) + Math.pow((height/2) - round, 2));
 // Calculate the distance from the rectangle's center to the lower edge of the
   // bottom-right rounded corner. When round
   // is 0, ry is equal to r.
   var ry = Math.sqrt(Math.pow((width/2) - round, 2) + Math.pow(height/2, 2));
 // Calculate angles. r1Angle is the angle between the X axis that runs through the
   // center of the rectangle and the line rx. r2Angle is the angle between rx and r.
   // r3Angle is the angle between r and ry. And r4Angle is the angle between ry and
   // the Y axis that runs through the center of the rectangle.
   var r1Angle = Math.atan( ((height/2) - round) /( width/2) );
   var r2Angle = Math.atan( (height/2) / (width/2) ) - r1Angle;
   var r4Angle = Math.atan( ((width/2) - round) / (height/2) );
   var r3Angle = (Math.PI/2) - r1Angle - r2Angle - r4Angle;
 // Calculate the distance of the control point from the 
   // arc center for the rounded corners.
   var ctrlDist = Math.sqrt(2 * Math.pow(round, 2));
 // Declare the local variables used to calculate the control point.
   var ctrlX, ctrlY;
 // Calculate where to begin drawing the first side segment and then draw it.
   rotation += r1Angle + r2Angle + r3Angle;
   var x1 = x + ry * Math.cos(rotation);
   var y1 = y + ry * Math.sin(rotation);
   this.moveTo(x1, y1);
   rotation += 2 * r4Angle;
   x1 = x + ry * Math.cos(rotation);
   y1 = y + ry * Math.sin(rotation);
   this.lineTo(x1, y1);
 // Set rotation to the starting point for the next side segment and calculate the x
   // and y coordinates.
   rotation += r3Angle + r2Angle;
   x1 = x + rx * Math.cos(rotation);
   y1 = y + rx * Math.sin(rotation);
 // If the corners are rounded, calculate the control point for the corner's curve
   // and draw it.
   if (round > 0) {
   ctrlX = x + r * Math.cos(rotation - r2Angle);
   ctrlY = y + r * Math.sin(rotation - r2Angle);
   this.curveTo(ctrlX, ctrlY, x1, y1);
   }
 // Calculate the end point of the second side segment and draw the line.
   rotation += 2 * r1Angle;
   x1 = x + rx * Math.cos(rotation);
   y1 = y + rx * Math.sin(rotation);
   this.lineTo(x1, y1);
 // Calculate the next line segment's starting point.
   rotation += r2Angle + r3Angle;
   x1 = x + ry * Math.cos(rotation);
   y1 = y + ry * Math.sin(rotation);
 // Draw the rounded corner, if applicable.
   if (round > 0) {
   ctrlX = x + r * Math.cos(rotation - r3Angle);
   ctrlY = y + r * Math.sin(rotation - r3Angle);
   this.curveTo(ctrlX, ctrlY, x1, y1);
   }
 // Calculate the end point of the third segment and draw the line.
   rotation += 2 * r4Angle;
   x1 = x + ry * Math.cos(rotation);
   y1 = y + ry * Math.sin(rotation);
   this.lineTo(x1, y1);
 // Calculate the starting point of the next segment.
   rotation += r3Angle + r2Angle;
   x1 = x + rx * Math.cos(rotation);
   y1 = y + rx * Math.sin(rotation);
 // If applicable, draw the rounded corner.
   if (round > 0) {
   ctrlX = x + r * Math.cos(rotation - r2Angle);
   ctrlY = y + r * Math.sin(rotation - r2Angle);
   this.curveTo(ctrlX, ctrlY, x1, y1);
   }
 // Calculate the end point for the fourth segment and draw it.
   rotation += 2 * r1Angle;
   x1 = x + rx * Math.cos(rotation);
   y1 = y + rx * Math.sin(rotation);
   this.lineTo(x1, y1);
 // Calculate the end point for the next corner arc and, if applicable, draw it.
   rotation += r3Angle + r2Angle;
   x1 = x + ry * Math.cos(rotation);
   y1 = y + ry * Math.sin(rotation);
   if (round > 0) {
   ctrlX = x + r * Math.cos(rotation - r3Angle);
   ctrlY = y + r * Math.sin(rotation - r3Angle);
   this.curveTo(ctrlX, ctrlY, x1, y1);
   }
   }

The preceding example will be clearer with a closer examination.

The ActionScript trigonometric methods require angles measured in radians. Therefore, whenever you specify an angle in degrees (which is generally easier for humans), you must convert the units to radians before passing them to ActionScript's trigonometric methods. In this case, we convert the rotation parameter from degrees to radians using the Math.degToRad( ) method.

rotation = Math.degToRad(rotation);

The length of the three imaginary lines used for drawing the rounded corners, are calculated using the Pythagorean theorem. In our example, these distances are:

var r  = Math.sqrt(Math.pow(width/2, 2) + Math.pow(height/2, 2));
   var rx = Math.sqrt(Math.pow(width/2, 2) + Math.pow((height/2) - round, 2));
   var ry = Math.sqrt(Math.pow((width/2) - round, 2) + Math.pow(height/2, 2));

Next, we must calculate the angles formed between the axes and the lines r, rx, and ry. These angles are used to determine the x and y coordinates of the starting and ending side segments. If you know the lengths of the sides of a right triangle, you can determine the angles that they form. Because the axes and the lines r, rx, and ry can be formed into right triangles you can determine the angles these lines form using the tangent and arctangent. The tangent in a right triangle is defined as the ratio of the side opposite the angle to the side adjacent to the angle. The arctangent is the inverse of the tangent function, so we use the following to determine the angles:

var r1Angle = Math.atan(((height/2) - round)/(width/2));
   var r2Angle = Math.atan((height/2)/(width/2)) - r1Angle;
   var r4Angle = Math.atan(((width/2) - round)/(height/2));
   var r3Angle = (Math.PI/2) - r1Angle - r2Angle - r4Angle;

The corners are each composed of a single curve that is a semicircle. To determine the distance between the semicircle's center point and the control point used to draw that curve, again use the Pythagorean theorem:

var ctrlDist = Math.sqrt(2 * Math.pow(round, 2));

The first thing you want to do when you draw the rectangle is to move the imaginary pen to a starting point on the rectangle without actually drawing a line. In this example, the calculated starting point is at the right end of the bottom segment (of an unrotated rectangle). If you know the distance between two points and the angle (the opposite angle formed by an imaginary right triangle with the known line being the hypotenuse), you can calculate the x and y coordinates of the destination point using trigonometric functions. The x coordinate is determined by the distance times the cosine of the angle. The y coordinate is determined by the distance times the sine of the angle. In this example the x and y coordinates (x1 and y1) are also offset by the x and y parameters to draw a rectangle whose center is not at (0, 0):

rotation += r1Angle + r2Angle + r3Angle;
   var x1 = x + ry * Math.cos(rotation);
   var y1 = y + ry * Math.sin(rotation);
   this.moveTo(x1, y1);

The remainder of the example follows the same pattern: draw a line, draw a rounded corner (if applicable), and then move to the next side segment. The new coordinates for each segment are calculated using the same process as described previously. Once you have defined and included the drawRectangle( ) method in your Flash document, you can quickly draw a rectangle within any movie clip instance. Don't forget that you still need to define the line style before Flash will actually draw anything.

// Create a new movie clip into which to draw the rectangle.
   this.createEmptyMovieClip("rectangle_mc", 1);
// Define a 1-pixel, black, solid line style.
   rectangle_mc.lineStyle(1, 0x000000, 100);
// Draw a rectangle with dimensions of 100   x   200. The rectangle has rounded corners
   // with radii of 10, and it is rotated 45 degrees clockwise.
   rectangle_mc.drawRectangle(100, 200, 10, 45);

You can draw a square by using the drawRectangle( ) method with equal height and width values:

this.createEmptyMovieClip("square_mc", 1);
   square_mc.lineStyle(1, 0x000000, 100);
   square_mc.drawRectangle(100, 100);

You can draw filled rectangles by invoking beginFill( ) or beginGradientFill( ) before drawRectangle( ) and invoking endFill( ) after drawRectangle( ):

this.createEmptyMovieClip("filledRectangle_mc", 1);
   filledRectangle_mc.lineStyle(1, 0x000000, 100);   // Define a black, 1-pixel border.
   filledRectangle_mc.beginFill(0x0000FF);           // Define a solid blue fill.
   filledRectangle_mc.drawRectangle(100, 200);
   filledRectangle_mc.endFill(  );
Leave a comment or ask a question
Total comments: 0

Flash Disclaimer

  • The e-articles directory is not responsible for any and all copyright infringements by writers and authors. If you suspect the information contained by this page for any copyright infringements, please contact us to investigate the issue
Targeting Flash Movie Clips - The simplest way to target a movie clip is to use its name, followed by a dot, followed by the command you want to send. However, there are plenty of other ways to target a movie clip as we (more...)
Using Mathematical Operators in ActionScript - You want to modify something over time, such as the rotation or position of a movie clip. Use the compound assignment operators to change a variable or property in increments. Or, if increm (more...)
How to build an animated button using Flash - Time: 15 Minutes. Difficulty Level: Intermediate Requirements: Flash 8 Assumed Knowledge: Basic action (more...)
Enhancing Standalone Projector - You want to create an enhanced Standalone Projector with features such as borderless playback, custom titles, no Flash menus, and so on. Use a third-party tool such as SWF Studio or SWFKit to c (more...)
Creating Flash Buttons - Buttons are one of the three main types of symbols that you use in Flash. The others are movie clips and graphics. Making a New Button There are many ways to create a button. One (more...)
Bouncing Ball Script - Start a new Flash movie. Create a movie clip that has a ball graphic inside it. You can name the instance of the movie clip, myClip, but our code will not depend on the name of the clip. (more...)
ActionScript: Creating Reusable Code - You want to perform a series of actions at various times without duplicating code unnecessarily throughout your movie. Create a function and then call (i.e., invoke) it by name whenever you (more...)
3D Scaling with ActionScript - Although Flash is not capable of real 3D graphics, the kind seen in popular computer games, you can create the illusion of 3D by using scaling. Scaling an object is a great way to give your (more...)
The Dot Syntax - Something else that you will be seeing a lot of as you learn ActionScript is dot syntax. Dot syntax is a way of grouping objects and functions that is used in many object-oriented programming (more...)
Movie Clip Scripts - Movie clip scripts, like button scripts, use handlers. Instead of using the on keyword that button scripts use, we will use the onClipEvent keyword. Here is an example of a movie clip script: (more...)

 
free content
    Copyright © 2006 - 2012 e-articles.info.
The texts, articles and tutorials in the directory are property of their respective owners and authors.