ActionScript and JavaScript - Part II

Downloading a Fla file

When a .fla is downloaded, a zip file will result. The zip file then can be unzipped and the .xfl file opened. If changes are made, then the file should be saved as an .fla file to preserve the changes.

Creating a Link

Suppose you want to create a link to http://www.gmu.edu First create a button symbol and then place an instance of the button symbol on the Stage and name it gmu_btn. Then add the following ActionScript. The variable name goURL_req and the function name goURL are arbitrary.

GMU_btn.addEventListener(MouseEvent.CLICK, gotoGMU);
function gotoGMU(event:MouseEvent):void
{
navigateToURL(new URLRequest("http://www.gmu.edu"), "_blank");
}

An example is at websiteas.fla. The navigateToURL is blocked by pop-up blockers in Internet Explorer in some cases - see https://helpx.adobe.com/flash-player/kb/pop-windows-blocked-ie-actionscript.html

------------------------

In JavaScript for HTML5 Canvas, the code would be (function names can again be whatever you want)

this.gmu_btn.addEventListener("click", gotoGMU);
function gotoGMU() {
window.open("http://www.gmu.edu", "_blank");
}

Pop-up blockers block window.open()

In either the ActionScript or the JavaScript approach, one can also designate links in a relative manner rather than using an absolute address such as http://www.gmu.edu

In Code Snippets for both ActionScript and HTML5 Canvas, one selects the instance of the button and then chooses Actions>Click to go to Web Page.

An example is at websitejs.fla. window.open() will likely be blocked by pop-up blockers.

Creating a Slide Show (Going to Next and Previous Frames in ActionScript)

One can create a slide show as follows:

1) Import pictures into Flash - name this layer suitably, e.g. pictures. You can use your own, or use those at www.billpegram.com/Flash/photos (taken from the GMU home page)

If there are n pictures, one wants to import these n pictures into n frames, one picture per frame. Choose File>Import>Import to Stage and select the first picture in the sequence. If the first one imported is part of a numbered sequence of pictures in the same folder, Flash will ask you whether you want to import all of them, and will import them in the order of their numbering within the file names.

2) Insert a layer and name it buttons and create a previous and next button and place an instance of these buttons into frame 1 of the button layer. Select a button instance and then in the Property Inspector name the instance appropriately, e.g. next_btn and prev_btn.

3) Insert a layer and name it actions and add ActionScript in frame 1 of this layer.

Add an eventListener for the instance of the previous button which will execute a previous function. Similarly for the next button. The functions will utilize the following methods:.

prevFrame(); -- this moves the timeline back one frame and stops
nextFrame(); - this moves the timeline forward one frame and stops

Thus the code would be like the following:

function forward(event:MouseEvent):void {nextFrame();} // the function name forward is arbitrary
next_btn.addEventListener(MouseEvent.CLICK, forward); // the second argument in the addEventListener is the name of the function defined in the function statement

function backward(event:MouseEvent):void {prevFrame();}
prev_btn.addEventListener(MouseEvent.CLICK, backward);

In Code Snippets for ActionScript, one selects the instance of the button and then chooses Timeline Navigation> Click to Go to Next Frame and Stop / Click to go to Previous Frame and Stop.

An example is slideshowas3.fla

Creating a Slide Show (Going to Next and Previous Frames in JavaScript for HTML5 Canvas)

The approach is similar to that in ActionScript but prefaces the instance name with the this keyword as before and uses this.currentFrame to get the number of the current frame .

this.stop(); // stops the main timeline
this.forward_btn.removeAllEventListeners(); // this removes all eventlisteners for the forward_btn button instance, otherwise they appear to pile up and cause problems
this.back_btn.removeAllEventListeners(); // this removes all event listeners for the back_btn button instance

this.next_btn.addEventListener("click", forward.bind(this)); // the second argument references the name of the function, which is arbitrary
function forward
{
this.gotoAndStop(this.currentFrame+1); //
}

this.back_btn.addEventListener("click", back.bind(this));
function back()
{
this.gotoAndStop(this.currentFrame-1);
}

Using Code Snippets for HTML5, one selects the instance of the button and choose Timeline Navigation>Click to Go to Frame and Stop. Inside the parentheses of the method, one writes this.currentFrame + 1 to go forward and this.currentFrame - 1 to go backward.

An example is slideshowcanvas.fla

Whereas similar code in ActionScript stops at the final frame going forward and at the initial frame going backward, the JavaScript above wraps around from the last image to the first image going forward, but going backward, it stops at the first image and does not wrap. Therefore, one way to provide a symmetrical experience going forward and backward in HTML5 Canvas is to introduce conditionals as was the case in ActionScript.

Enhancing the Slide Show (Use of Conditionals and Going to a Specified Frame in ActionScript)

Using the above methods in ActionScript, if one is at the last frame, the nextFrame() will result in no change. If one wants instead to go to the first frame, one would instead change the body of the forward function to use a conditional statement:

if (currentFrame == totalFrames) gotoAndStop(1);
else nextFrame();

If one is at the first frame, and one clicks the back button, the prevFrame() will result in no change. If one wants instead to go to the last frame, one would instead change the body of the backward function to use a conditional statement:

if (currentFrame == 1) gotoAndStop(totalFrames);
else prevFrame();

Note that currentFrame and totalFrames are variables that refer to the number of the current frame and the total number of frames in the movie, respectively.

An example is slideshowenhancedas3.fla

Enhancing the Slide Show (Use of Conditionals and Going to a Specified Frame in JavaScript)

In JavaScript, instead of using totalFrames, one uses this.timeline.duration. Also even though in Flash design mode, frames begin with 1, in JavaScript they begin with 0. The removing of the eventlisteners from the buttons was added to fix a problem that the slideshow was skipping an image the second time through - one website said they were "piling up".

this.stop();
this.forward_btn.removeAllEventListeners();
this.back_btn.removeAllEventListeners();

this.forward_btn.addEventListener("click", forward.bind(this));

function forward() {
if (this.currentFrame+1 == this.timeline.duration) {
this.gotoAndStop(0); }
else this.gotoAndStop(this.currentFrame+1); }

this.back_btn.addEventListener("click", back.bind(this));

function back() {
if (this.currentFrame == 0) this.gotoAndStop(this.timeline.duration-1);
else this.gotoAndStop(this.currentFrame-1);
}

An example is slideshowenhancedcanvas.fla

Creating "Multipage" Content with a Navigational Bar within a Flash Movie Using ActionScript

Consider a simple multi-page website, i.e. with several html pages. Now we will create a Flash movie which has the content from these html pages We will put the content of each html page into a frame in the Flash movie and then create button symbols which when the instance is clicked, the movie will go to and stop at the frame which has the specified content.

1) Create a labels layer - To label a frame, make sure there is a keyframe in that frame and then click on the frame -- in the Properties panel, one can give the frame a name. In this exercise, each label should correspond to a page in the original site. Remember to create a blank keyframe in any frame that you want to name. For the label to be visible, there have to be enough frames for you to see the label; if not, press F5 to add frames until the entire label is visible.

2) Create a content layer - Put each "page" of content into the content layer in frames that correspond to the frames that are labelled. Again there will have to be keyframes in each frame containing content (use F7 to add a blank keyframe)

3) Create a buttons layer - Create a separate button symbol corresponding to each content frame and then place an instance of the button symbol in the button layer. Since the artwork on these buttons will differ, one must create separate symbols for each button, but it may be easier to duplicate an existing button and then modify the content. Name each button instance appropriately in the Property Inspector.

4) Create an actions layer - Add a stop(); command to stop the main timeline. Suppose the button instances and frames are both named bkgd and aboutus. Then the code would be:

function buttonClick1(event:MouseEvent):void {gotoAndStop("bkgd"); }
function buttonClick2(event:MouseEvent):void {gotoAndStop("aboutus"); }

bkgd.addEventListener(MouseEvent.CLICK, buttonClick1);
aboutus.addEventListener(MouseEvent.CLICK, buttonClick2);

You might think that in such a framework where each "page" resides in a separate frame which is accessed only through a "go to and stop" action when one clicks a button, that there is no room for animation. However, if one places a movie clip in one of these frames, the clip will play because movie clips play even when the main Timeline is stopped.

For an example of this, see websiteas.fla

Creating "Multipage" Content with a Navigational Bar within a Flash Movie Using JavaScript

The steps are similar to those for ActionScript. Here the use of frame labels is particularly convenient since frame numbers in EaselJS start at 0 instead of 1. For example, this affects gotoAndStop and gotoAndPlay calls.

this.stop();
this.home_btn.addEventListener("click", home.bind(this));
function home() {this.gotoAndStop("home"); }

this.history_btn.addEventListener("click", history.bind(this));
function history() {this.gotoAndStop("history"); }

this.aboutus_btn.addEventListener("click", aboutus.bind(this));
function aboutus() {this.gotoAndStop("aboutus"); }

The websitejs.fla file shows the result. When one uses HTML5 Canvas, if one's buttons consist of Text, it is important to use the hit state with a shape such as a rectangle, to define the clickable area of the button.

-----------------------------------------------------

Enhancing the Buttons for "Multipage" Content with a Navigational Bar within a Flash Movie Using ActionScript

In the above example, the button corresponding to the "current page" still functions like a button. Often in a website, one prefers to disable a link that goes to one's current location, so as to give the user a better sense of where they are. There are at least two ways to accomplish this in a Flash movie using ActionScript.:

1) ActionScript solution - Instead of the above code, one would add additional statements that would enable all buttons other than the current button and disable the current button. It is necessary to enable other buttons since they might have been disabled by a previous mouse click on that button.

function home(event:MouseEvent):void {gotoAndStop("home");
history.
aboutus.enabled = true;
bkgd.enabled = false; }

function buttonClick2(event:MouseEvent):void {gotoAndStop("aboutus");
aboutus.enabled = false;
bkgd.enabled = true; }

bkgd.addEventListener(MouseEvent.CLICK, buttonClick1);
aboutus.addEventListener(MouseEvent.CLICK, buttonClick2);

2) Turning button symbols into graphic symbols

In the previous solution, one places an instance of each button in the initial frame and adds frames to the button layer so that these button instances are visible in the subsequent frames that hold the content for the other "pages" in the site.

Another approach requires one to place an instance of each button in the buttons layer for each frame that is labelled (in the frames layer). Select the button instance referring to the current frame and in the Properties Panel, change the button symbol to a graphic symbol. It will no longer function as a link.

Streamlining the ActionScript Where Multiple Buttons are Involved

In the initial solution, there is a separate function corresponding to each button. One can instead use a single function if one names the frames and button instances to match. When one clicks on the button, this triggers an event and this event has properties, one of which is target -- this property stores the name of the object that initiates the event (in this case, the name of the button instance)

function buttonClick(event:MouseEvent):void {
gotoAndStop(event.target.name);
aboutus.enabled = true;
bkgd.enabled = true;
event.target.enabled = false; }
}

bkgd.addEventListener(MouseEvent.CLICK, buttonClick);
aboutus.addEventListener(MouseEvent.CLICK, buttonClick);

-----------

Thus, because we are able to get the name of the button when we click it, we are able to write a single buttonClick function to go to the desired frame, enable all buttons, and then disable the button that initiated the event.

Revised: April 26, 2016. Comments to William Pegram, bill@billpegram.com