DCFLASH Tutorial: Shape Basics

Author: Darren Cook
Last Update: 2006-12-22

Final product of this tutorial

Introduction

This tutorial will introduce the Shape, Line and Gradient classes of dcflash (an open source actionscript 2 library, principally for charting). These classes are the low-level building blocks of the charting classes, controlling appearance, but they can also be useful in their own right.

Line describes the appearance of a pen, then supplies many functions to draw shapes with that pen.

Shape describes a line and a fill, then supplies many functions to draw filled shapes.

In other words, Line and Shape are wrappers around ActionScript's lineStyle() and beginFill(), but with lots of useful drawing functions attached.

Gradient is used with the shape class for when you wish your shape to have a gradient fill. It is a thin wrapper around ActionScript's beginGradientFill() function. Thin, but very helpful.

Hello Rectangle

An introduction to a new language shows how to output Hello World, but I think to introduce a drawing library we should show how to display a rectangle. Here it is:

import org.dcflash.Line

class ShapeBasics{

public static function main(){
var line:Line=new Line();
line.setCanvas(_root);
line.drawRectangle(10,110,200,100);
}

}

Save that to a file called ShapeBasics.as and if using mtasc you could compile with:

mtasc -strict -swf ShapeBasics.swf -header 480:240:16 \
      -main -version 6 -cp /your/classpath ShapeBasics.as

It draws a black rectangle, with upper-left at (10,10), 200 pixels wide, 100 pixels high. Note that drawRectangle() takes the origin in the bottom-left. When you create a line with no constructor parameters it defaults to black, 1 pixel width, fully opaque.

The only other line of code is the call to setCanvas(). This specifies which movieclip you wish to draw on. We are keeping it simple here and drawing on _root.

Fill Me Up

The Line and Shape classes have mostly the same drawing functions: take a look at the source to see them all. A Shape object is created by specifying a line for the boundary, then a fill color and an opacity. If you don't specify them then you get the same color and opacity as the Line instance. So, this next example will draw a black circle in our rectangle. The first two parameters to drawCircle are the centre point, the third parameter is the radius:

import org.dcflash.Line
import org.dcflash.Shape

class ShapeBasics{

public static function main(){
var line:Line=new Line();
line.setCanvas(_root);
line.drawRectangle(10,110,200,100);

var shape:Shape=new Shape();
shape.setCanvas(_root);
shape.drawCircle(50,50,40);

}

}

Yawn. Let's spruce things up. First with some red lines, then with a yellow fill. And, while here, we will add an overlapping ellipse which is half-transparent:

import org.dcflash.Line
import org.dcflash.Shape

class ShapeBasics{

public static function main(){
var line:Line=new Line(2,0xFF0000);
line.setCanvas(_root);
line.drawRectangle(10,110,200,100);

var shape:Shape=new Shape(line,0xFFFF00);
shape.setCanvas(_root);
shape.drawCircle(50,50,40);

var shape2:Shape=new Shape(new Line(null),0x00FFFF,0.5);
shape2.setCanvas(_root);
shape2.drawEllipse(80,80,60,30);

}

}

The parameters to drawEllipse() are similar to drawCircle() but with radii in both the x and y axes. So 60,30 means twice as wide as it is high.

Let's tackle the three parameters to the Shape constructor one by one. "new Line(...)" means we create a Line object just where we need it. Its null parameter means no line at all.

Next, 0x00FFFF is the code for cyan. Finally 0.5 means 50% opaque. 1.0 is the default, meaning fully opaque. 0.0 would mean completely transparent, and thus invisible. If you wanted an invisible fill you could do this. Or you could simply use a Line object instead of a Shape object!

Fading Out

The documentation for ActionScript's beginGradientFill() reads like an article on higher mathematics. But most of the time if you want a gradient you just want to blend one color to another. The Gradient class in dcflash offers three init functions. initCustom() has the same parameters as beginGradientFill(). See the official documentation. Have fun.

Then we have initLinear() for horizontal/vertical blends, and initRadial() for radial blends. These still take quite a few parameters, but they are about as easy as they can be. Here we add a rectangle that goes from red to blue, with a black border, and a circle that is green in the middle and yellow at the edges.


import org.dcflash.Line
import org.dcflash.Shape
import org.dcflash.Gradient

class ShapeBasics{

public static function main(){
var line:Line=new Line(2,0xFF0000);
line.setCanvas(_root);
line.drawRectangle(10,110,200,100);

var shape:Shape=new Shape(line,0xFFFF00);
shape.setCanvas(_root);
shape.drawCircle(50,50,40);

var shape2:Shape=new Shape(new Line(null),0x00FFFF,0.5);
shape2.setCanvas(_root);
shape2.drawEllipse(80,80,60,30);

var shape3:Shape=new Shape(new Line());
shape3.setCanvas(_root);
shape3.gradient=new Gradient();
shape3.gradient.initLinear(0xFF0000,0x0000FF,1.0,1.0,10,120,200,100);
shape3.drawRectangle(10,220,200,100);

var shape4:Shape=new Shape(new Line(0));
shape4.setCanvas(_root);
shape4.gradient=new Gradient();
shape4.gradient.initRadial(0x00FF00,0xFFFF00,1.0,1.0,320,105,100,100);
shape4.drawCircle(320,105,100);

}

}

For the linear gradient we wanted the gradient to fit exactly within our rectangle, so we specify the same parameters as the drawRectangle(), except the origin is in the top-left, not bottom-left. The two 1.0 parameters mean it is fully opaque at both the left and right. Note that it is possible to have a gradient that is the same colour at both ends but just the amount of transparency changes. E.g.shape3.gradient.initLinear(0xFF0000,0xFF0000,1.0,0.0,10,120,200,100); would have strong red at the left fading out to white on the right. Not much different from fading from red to white unless you have something behind it of course. You can also have a gradient of both colours and transparency at the same time. E.g. shape3.gradient.initLinear(0xFF0000,0x0000FF,0.5,1.0,10,120,200,100); fades from red to blue again, but the red is half-transparent and as the color changes to blue it becomes more solid.

If you wanted a gradient from top to bottom instead of left to right then there is an extra optional parameter for rotation. You would give this as Math.PI/2. You can also experiment with other angles, and experiment with having the gradient coordinates differ slightly from those of the rectangle.

The first four parameters to the radial gradient are the same: start and end colors, start and end opacity. Then the next two parameters are the centre of the ellipse. And the last two parameters are the radii of the ellipse. We have a circle so we set the X and Y radii to both be 100.

Remember there is nothing to stop you having a radial gradient in a rectangle, or a linear gradient in a circle. Think of the gradient as covering some region (the origin and width/height/radius you give the gradient), and the shape you draw as just being a cut-out to make part of it visible.

Summary

This tutorial has stuck with circles and rectangles but there are more interesting shapes (including support for general polygons, and some pseudo-3D shapes) in the Line and Shape classes.

I suggest using semi-transparency liberally - it is only one parameter to change but can be a big jump in visual impact. The same with gradients. The downside is it puts more load on the CPU, so may make animations run more slowly.

The source code for the final version is available here: ShapeBasics.as.


© Copyright Darren Cook, 2006

About The Author: I am a freelance programmer, British but living and working in Tokyo, Japan. You can learn more about my skills and experience at http://dcook.org/work/, see some more of my charts at http://dcook.org/work/charts/ and you can contact me directly at darren@dcook.org.





 

Work Top Page   *   Personal Home Page   *   Email me at: darren@dcook.org   *   PGP Public Key

Last updated: 18th Dec 2006, © Copyright Darren Cook, 2006.

No Software Patents