Tutorials, extensions, and source files for ActionScript, Flash, and other Adobe products.


Pages: 1 | 2 | 3 | 4 | 5


Throughout this article, we've covered all sorts of Auto Shapes and quite a few techniques used in their creation. Hopefully it was enough to help you get started on making your own. The following outlines key points covered.

• Fireworks Auto Shapes are defined completely by JavaScript from files in your Configuration\Auto Shapes or Configuration\Auto Shape Tools folders in your Fireworks install directory.

• Previews for Auto Shapes are GIF or PNG and reside with your Auto Shape JavaScript file. For shapes in the Shapes panel, previews are 60x60 while Auto Shape tool previews are 16x16.

• Auto Shapes consist of one or more elements that can be either a path, text or a group.

• Path elements consist of one of more contours each of which consist or one or more nodes. Nodes in turn are made up of a main point and two control points, a predecessor and a successor.

• The smartShape object provides you with variables and functions to help you create and manage your shapes.

• Creating Auto Shapes should always revolve around the position of the mouse found in smartShape.currentMousePos.

• Events that call your Auto Shape script are specified in smartShape.operation.

• Movement for control points and nodes can be handled through the various register move functions.

• A register move parameters object for register move functions is created from smartShape.GetDefaultMoveParms() and lets you specify how the various register move functions move points.

• Colors and effects can be added to elements within an Auto Shape by altering those elements' pathAttributes and effectList objects.

• Characters in text elements can only be assigned or changed when reassigning that elements entire textRuns property.

• Moving text in an Auto Shape requires adjusting the text's rawLeft and rawTop properties.

• Bitmap visuals can be added to Auto Shapes through patterns on a path. You just need to be sure those patterns are installed for Fireworks.

• Auto Shape tools are much like Auto Shapes from the Shapes panel except they receive more creation events and can use RegisterInsertBBoxMove for point movement during shape creation.

• Auto Shapes can be shapes, tools as well as utilities that help you perform other actions not associated with that shape directly.

• Creating circular curves for paths requires the use of fw.ellipseBCPConst.

• Study the Extending Fireworks documentation and watch out for Auto Shape bugs. Do this and you should be well off in your efforts towards creating your own custom Auto Shapes.


Completed Shapes

  Shape Versions
Curve (1, 2)
Hollow Box (1, 2, 3, 4, 5, 6, 7)
Play Button Triangle (1, 2, 3, 4)
Register Moves (1, 2)
Asterisk (1, 2, 3)
Pentagon (1, 2, 3, 4)
Text Wave  
Aqua Button  
Simple Arrow  
Element Matcher  
Chained Selection (1, 2)
Circle Segment  
Rounded Polygon  


Useful Variables and Functions

var mouse = smartShape.currentMousePos; // short variable for mouse position
var clicked = smartShape.mouseDownPos; // short variable for mouse down position
var cps = smartShape.elem.controlPoints; // short variable for control points array
var elems = smartShape.elem.elements; // short variable for smartShape elements array
var data = smartShape.elem.customData; // short variable for smartShape customData object

var rad90 = Math.PI/2; // 90 degrees in radians
var rad180 = Math.PI; // 180 degrees in radians
var rad270 = 3*Math.PI/2; // 270 degrees in radians
var rad360 = 2*Math.PI; // 360 degrees in radians
var toDegrees = 180/Math.PI; // multiply this by a radians angle to get it in degrees
var toRadians = Math.PI/180; // multiply this by a degrees angle to get it in radians

 * The following are functions for all smartShape Events
var operation = new Object();
operation.InsertSmartShapeAt = function(){}
operation.BeginDragInsert = function(){}
operation.DragInsert = function(){}
operation.EndDragInsert = function(){}
operation.BeginDragControlPoint = function(){}
operation.DragControlPoint = function(){}
operation.EndDragControlPoint = function(){}
operation.SmartShapeEdited = function(){}
// used to invoke the above events at the bottom of your script
if (operation[smartShape.operation]) operation[smartShape.operation]();

 * SetBezierNodePosition sets the position of the passed node to the
 * position of the point pt parameter. All node control points are
 * set to this point as well
 * Requires: SetBezierNodePosition
SetNodePosition = function(node, pt){
	SetBezierNodePosition(node, pt,pt,pt); // set point position for all nodes to pt

 * SetBezierNodePosition sets the position of the passed node to the
 * position of the points ptp (node predecessor), pt (main point), and
 * pts (node successor)
SetBezierNodePosition = function(node, ptp, pt, pts){
	node.predX	= ptp.x;	node.predY	= ptp.y; // Predecessor point
	node.x		= pt.x;		node.y		= pt.y; // Main points
	node.succX	= pts.x;	node.succY	= pts.y; // Successor points

 * MatchBezierNodePosition assigns to a node the position as specified
 * by another node passed in as match. 
MatchBezierNodePosition = function(node, match){
	node.predX	= match.predX;	node.predY	= match.predY; // Predecessor points
	node.x		= match.x;		node.y		= match.y; // Main points
	node.succX	= match.succX;	node.succY	= match.succY; // Successor points

 * SetControlPoint sets properties for the index'th control point of
 * smartShape.controlPoints, creating it in the array if it does not
 * yet exist. Only index and pt (point representing location) are
 * required parameters.
SetControlPoint = function(index, pt, /* optional: */ name, toolTip, type, toolTipTracksDrag, visible, hiliteDragOverObject){
	var cps = smartShape.controlPoints; // short variable for control points array
	if (index >= cps.length) cps.length = index+1; // create new control point by altering cps length if doesn't already exist
	cps[index].x = pt.x;	cps[index].y = pt.y; // set position of control point
	if (type != undefined) cps[index].type = type; // String representing type: "default", "defaultInverted" or "crossHair"
	if (name != undefined) cps[index].name = name; // String representing name
	if (toolTip != undefined) cps[index].toolTip = toolTip; // String representing tool tip
	if (toolTipTracksDrag != undefined) cps[index].toolTipTracksDrag = toolTipTracksDrag; // true/false for whether tool tip follows mouse in drag
	if (visible != undefined) cps[index].visible = visible; // true/false hide or show tool tip (it remains active while true)
	if (hiliteDragOverObject != undefined) cps[index].hiliteDragOverObject = hiliteDragOverObject; // true/false when true, hilites objects when dragged over them

 * CPoint creates a generic point object from a control point object
CPoint = function(index){
	return {x: cps[index].x, y:cps[index].y}; // copy x and y properties in returned object

 * NPoint creates a generic point object from a ContourNode object
NPoint = function(node){
	return {x: node.x, y:node.y}; // copy x and y properties in returned object

 * AddPoints adds two points pt1 and pt2 and returns the resulting point
AddPoints = function(pt1, pt2){
	return {x:pt1.x + pt2.x, y:pt1.y + pt2.y}; // add x and y properties in returned object

 * SubtractPoints subtracts two points pt1 and pt2 and returns the resulting point
SubtractPoints = function(pt1, pt2){
	return {x:pt1.x - pt2.x, y:pt1.y - pt2.y}; // subtract x and y properties in returned object

 * PointsEqual compares points pt1 and pt2 and returns true if they equal, false if not
PointsEqual = function(pt1, pt2){
	return (pt1.x == pt2.x && pt1.y == pt2.y); // return comparison of both x and y properties (true if both equal)

 * DistanceBetween uses the pythagorean theorem to determine the true distance
 * between two points pt1 and pt2.
DistanceBetween = function(pt1, pt2){
	var dx = pt2.x - pt1.x, dy = pt2.y - pt1.y; // find differences of point locations
	return Math.sqrt(dx*dx + dy*dy); // pythagorean theorem

 * PointBetween returns a point location between points pt1 and pt2
PointBetween = function(pt1, pt2){
	return {x:(pt1.x + pt2.x)/2, y:(pt1.y + pt2.y)/2}; // return average point between 2 points

 * AngleBetween returns the angle between two points pt1 and pt2 in radians
AngleBetween = function(pt1, pt2){
	return Math.atan2(pt2.y - pt1.y, pt2.x - pt1.x); // use arc tangent 2 to get angle

 * PointFromVector returns a point extending outward from the point origin at the
 * angle angle (radians) with a distance of power
PointFromVector = function(origin, angle, power){
	return {
		x: origin.x + Math.cos(angle)*power,
		y: origin.y + Math.sin(angle)*power
	}; // use sine and cosine to determine new point locations

 * RotatePointAroundPoint returns the location (point) of a point pt which has
 * been rotated around the point origin at an angle of angle (radians)
RotatePointAroundPoint = function(pt, origin, angle){
	var ca = Math.cos(angle),	sa = Math.sin(angle); // get sine and cosine values for the angle
	var dx = pt.x - origin.x,	dy = pt.y - origin.y; // get the differences in x and y locations
	return {x:origin.x + dx*ca - dy*sa, y:origin.y + dx*sa + dy*ca}; // return rotated point


Find More Auto Shapes

There aren't many Auto Shapes out there yet. Hopefully as more people read this, more will pop up after peopleas it becomes more clear just how to make them. Those I am aware of that are available for download and/or purchase can be found at the following locations.

Community MX
Macromedia Fireworks Exchange


Thank you for reading. Hopefully I've provided some insight, and hopefully I'll be seeing some new custom Auto Shapes appearing out there on the web or in the exchange. If you create and Auto Shape and want me to link to it, or maybe just have some questions/concerns/corrections for this article, drop me a line at senocular at hotmail dot com.

- senocular


Pages: 1 | 2 | 3 | 4 | 5