Invisible Button Command - Part I

Welcome and thank you for reading my first blog entry which will be the initial installment of what I hope to be a vast and comprehensive collection of thoughts, reviews, dissections and tutorials around Flash, ActionScript and Flex. So please, post comments and let me know how I’m doing.

For my first entry I’m going to go through the process of writing a simple but useful command to extend the Flash IDE using JSFL. Afterwards we’ll go through the process of packaging your command into an MXP.

Introduction

Having created a lot of Flash banner ads I grew tired of adding invisible buttons the size of the stage to each creation. Then it dawned on me, wouldn’t it be cool if there was a command to do this for me?

Let’s sum up the feature list for this new command:

  1. A button will be added to the library named “invisible”
  2. The button will contain a rectangle shape on the hit area frame
  3. The button will be placed on the stage in a new layer named “Button”
  4. The button will be resized to match the size of the stage and moved to 0,0
  5. ActionScript will be added to the button for interactivity
  6. When clicked, a dialog box will open for command options
  7. The new command will be listed in the commands menu of the IDE

Now that we know what we are building we can break it down into a series of steps that we’ll build upon.

If you are not using the Flash Professional you will need to use an alternate text editor like Notepad or Homesite to edit your JSFL files.

Step 1

Create a folder on your desktop named “My Commands”. This folder can be anywhere really, but it’ll be easier to follow if we have it in the same place. Open Flash and select File > New… and choose Flash JavaScript file. Save this file to your “My Commands” folder as “Invisible Button.jsfl” but don’t close it as we’ll be writing to it.

Double-clicking on the file will not open the script up for editing in Flash. Instead, the Flash IDE opens and tries to run the command. To edit JSFL files, you will need to open it from within Flash Pro.

Step 2

After your document is saved we’ll add some test code to make sure things are running properly. Type the following code into your Invisible Button.jsfl document:

var flash_doc = fl.getDocumentDOM();
var flash_lib = flash_doc.library;
var flash_tl  = flash_doc.getTimeline();
var flash_w = flash_doc.width;
var flash_h = flash_doc.height;

fl.trace("flash_doc: " + flash_doc);
fl.trace("flash_lib: " + flash_lib);
fl.trace("flash_tl: " + flash_tl);
fl.trace("flash_w: " + flash_w);
fl.trace("flash_h: " + flash_h);

You’ll notice I didn’t use strict typing for my variables. This is because we are coding with JavaScript. It’s easy to forget this and think you are coding with ActionScript because of the similar syntax and AS like methods such as trace().

Save your document. Now, create a new Flash document by going to File > New… Flash Document. If your defaults are unchanged you should now have an empty movie 550×400 pixels in size. Let’s test our new command and see how it works. With the empty Flash document in focus run the command by going to Commands > Run Command…. You will be presented with an open file dialog box. Simply browse for and select the Invisible Button.jsfl file we just created and click Open. If the command executes properly, your Output window should open and trace five lines from our script as follows:

flash_doc: [object Document]
flash_lib: [object Library]
flash_tl: [object Timeline]
flash_w: 550
flash_h: 400

Step 3

Next we’ll start adding some features from out list. We’ll skip the dialog box for now and begin with the button. We add a Button item to the library with the name “invisible”.

var symbolname = "invisible";
flash_lib.editItem(symbolname);

The addNewItem( type [, namePath] ) method of the library object enables you to add any new type to the library such as button or movie clip for example and assign it a name. The first parameter is the type and in our case “button”. The second parameter is the name for our symbol and we are going to name it “invisible”.

Save the document and flip over to the empty FLA we have been using for testing. Run the command the same way we did earlier and you will see a new button symbol added to your library. Overachievers who clicked the command twice may have noticed a slight bug. Running the command a second time gives you an error message stating “The name invisible is already taken. Please use a different name.” There are a number of ways to solve this issue. I’m going to assume a few things: one that I’m writing this tool for myself to use and not to resell, two that I’ll likely know if I already have an invisible button before clicking and three if I know I have one and I’m clicking anyway I likely want to replace the one I have with a new one. Your assumptions may be different than mine so you may choose to loop through incrementing names until you find one not taken. For the sake of this tutorial, but mostly because I’m the one writing it, we’ll go with my assumptions and choose to delete the existing version of the invisible button. Here’s how:

var symbolname = "invisible";

// Check the library to see if the symbol already exists
// if it does delete it
while (flash_lib.itemExists(symbolname))
{
  flash_lib.deleteItem(symbolname);
}
// Add the new symbol to the library
flash_lib.addNewItem("button", symbolname);

Simple enough, right? We now have the button symbol in the library and correctly named so we can scratch feature #1 off our list.

Step 4

We now have an empty button. What we need to do next is add a rectangle shape to it’s hit area frame. The way to do this is by entering edit mode, draw on the stage and exit editing mode.

flash_lib.editItem(symbolname);

To edit a symbol in the library we call the editItem([ namePath ]) method of the library object passing it the name of the symbol we wish to edit. Doing this has pretty much the same effect as if you were to double click on the symbol in the library and it would open for editing. The exitEditMode() method of the library object closes the symbol and returns you to the stage. We’ll wait until after we draw to implement the exit method.

Step 5

We need to implement some drawing while we have the symbol in edit mode. To do this we need to obtain a reference to the current timeline. Keep in mind the reference we already stored as flash_tl is a reference to _root’s timeline. Once we enter edit mode on a symbol the timeline changes to that of the symbol. To establish a reference to the symbol’s timeline we grab it the same way we did for _root.

button_tl = flash_doc.getTimeline();

This can get confusing since it’s the same exact call. It’s important you understand and pay attention to the context of this call. You need to know what timeline you are viewing when you grab a reference to it. Since the previous line of code was a call to editItem we know which timeline we are viewing.

Since we want to edit the Hit Area frame of the button we need to have a keyframe on frame 3 (frames are zero based so frame at index 3 is actually the 4th frame. A button’s four frames are labeled up, over, down and hit in that order.)

button_tl.insertKeyframe(3);
button_tl.currentFrame = 3;

By setting the timeline object’s currentFrame property to 3 we move the playback head to that frame. Any drawing we do will be on the stage at this frame. However, the drawing isn’t done on the timeline’s object reference; it’s done on the document’s object reference.

flash_doc.addNewRectangle({left:0, top:0, right:flash_w, bottom:flash_h}, 0);
flash_doc.selectAll();
flash_doc.breakApart();
flash_doc.setFillColor("#000000");
flash_doc.setStroke("#00000000", 1, "solid");
flash_doc.selectNone();

We’ve successfully drawn a rectangle on the Hit Area frame of our invisible button symbol. Now we can exit editing mode and scratch off feature #2 from our list.

flash_doc.exitEditMode();

Step 6

The button is complete so we can add it to the stage on the _root’s timeline. We do this by calling the addNewLayer([name] [, layerType [, bAddAbove]]) method of our flash_tl timeline object reference. This method returns an id which we will use to select the layer.

// Create a new layer for this symbol and rename it to button
var layerNum = flash_tl.addNewLayer();
flash_tl.setSelectedLayers(layerNum, true);
flash_tl.setLayerProperty("name", "button");

The setLayerProperty(property, value [, layersToChange]) method of the timeline object enables us to set the name of the layer to “button”.

Now that we have the layer both named and selected we can add symbol instances to it.

// Place the button on the stage and add the actionscript
flash_lib.addItemToDocument({x:flash_w/2, y:flash_h/2}, symbolname);

Using the library object reference we place the invisible button symbol on the stage using the addItemToDocument(position [, namePath]) method. By adding an item to the document it automatically becomes selected. Since we know it’s the only thing selected we can simply reference index zero of the selection array. Next we’ll add ActionScript to the button click. (_root.clickTag is a variable most media placement companies like DoubleClick use for passing urls into the SWF). These values are hard-coded for now but will be part of the options dialog in Part II of this tutorial.

flash_doc.selection[0].actionScript = "on (release) {\n\tgetURL(_root.clickTag, \"_blank\");\n}";
flash_doc.selectNone();

We’ve now completed features #3, #4 and #5! Save and run your command to see it in action!!

We’ll tackle adding an options dialog box to this command in Part II of this series and in Part III we’ll roll the command up into a nice clean MXP for professional Macromedia Extension Manager installs.

I hope you enjoyed this tutorial and found it easy to follow. Look for the next two parts of this series.

Here’s Part I of the JSFL in its entirety:

/**
 * Invisible Button.jsfl (Part 1 of 3 part series)
 * JSFL Command that adds an invisible button to the library of an open
 * FLA and places that button on to the current timeline at the height
 * and width of the stage.
 *
 * Author: James O’Reilly - JOR
 *         www.jamesor.com
 *
 * This work is licensed under the Creative Commons attribution 2.5
 * This comment block must remain intact.
 */
var flash_doc = fl.getDocumentDOM();
var flash_lib = flash_doc.library;
var flash_tl  = flash_doc.getTimeline();
var flash_w = flash_doc.width;
var flash_h = flash_doc.height;

var symbolname = "invisible";

// Check the library to see if the symbol already exists
// if it does delete it
while (flash_lib.itemExists(symbolname))
{
  flash_lib.deleteItem(symbolname);
}
// Add the new symbol to the library
flash_lib.addNewItem("button", symbolname);
flash_lib.editItem(symbolname);

// Draw the button
button_tl = flash_doc.getTimeline();
button_tl.insertKeyframe(3);
button_tl.currentFrame = 3;
flash_doc.addNewRectangle({left:0, top:0, right:flash_w, bottom:flash_h}, 0);
flash_doc.selectAll();
flash_doc.breakApart();
flash_doc.setFillColor("#000000");
flash_doc.setStroke("#00000000", 1, "solid");
flash_doc.selectNone();

// Exit edit mode and add the symbol to the stage
flash_doc.exitEditMode();

// Create a new layer for this symbol and rename it to button
var layerNum = flash_tl.addNewLayer();
flash_tl.setSelectedLayers(layerNum, true);
flash_tl.setLayerProperty("name", "button");

// Place the button on the stage and add the actionscript
flash_lib.addItemToDocument({x:flash_w/2, y:flash_h/2}, symbolname);
flash_doc.selection[0].actionScript = "on (release) {\n\tgetURL(_root.clickTag, \"_blank\");\n}";
flash_doc.selectNone();

Download Part I source code

4 Responses to “Invisible Button Command - Part I”

  1. James O’Reilly » Blog Archive » Invisible Button Command - Part II Says:

    […] « Invisible Button Command - Part I […]

  2. Amy Says:

    Hi James, I found this tip very helpful as I am busy making banners and looking for shortcuts to speed up my production.

    I prefer to put all (or as much as possible) my AS on frame 1 of the main timeline. Where can I find information to edit this script to place the clickTag reference on that frame and give the button an instance name? I am reviewing the Help menu on Extending but it’s a bit daunting since this is my first exposure to JSFL.

  3. James O'Reilly Says:

    On the Adobe Dev Center page for JSFL you can find links to both HTML and PDF versions of the Flash 8 JSFL Reference Manual. The link is http://www.adobe.com/devnet/flash/javascript_api.html.

  4. keyhodges Says:

    hey James I am building a site and I have no ideal how to make a button perform more then one task.
    second ? could one use or hint to a button thats already created

Leave a Reply


Bad Behavior has blocked 605 access attempts in the last 7 days.