The Ultimate Slide Show MX

By Joachim Schnier

Introduction

Here is what you learn
1. a dynamic menu, which can be externally manipulated;
2. automatic slide advancement;
3. preloading of slides for individual frames;
4. complete management of slides from external files. The .swf file once set up does not have to be changed any more. However, the fla file has to be opened and the movie exported again.

This tutorial will show you how to set up the slide show. What is different to other slideshow files for example the one presented as a template in Flash MX? The big difference is that we do not have to create one frame for one slide but one frame for a series of slides, which we control by actionscript. By this way we can show a large number of slides (about 100-200 for 10 fames) and still maintain control without getting lost in a forest of frames. Have a look at the sample file.

The SWF

Download files here.



Creating the menu

The dynamic menu has been described in the Flash 5 Bible. We first create two frames for the menu and all the actionscript, which we distribute over the two frames. For the menubutton we make a movieclip (´menuitem´)containing a button graphic, which we animate. We then insert a dynamic textfield into the graphic, which we name ´textField´. In the ´var´ box for the textfield we enter the variable name ´labelName´. We then make a new movieclip and insert an instance of the menuitem, which we give the name ´menu´. Click on the instance and enter the movieclip name ´menuitemBase´ in the property inspector. Then place an instance of the menu button on the scene in frames 1 and 2 and name this movie clip ´menu´. Next write the actionscript into an external menu and enter this code into an action frame in frame 1:

#include "menu_code.txt"
Enter the following code into an external file, which we call ´menu_code´:
//dynamic menu: code from Flash 5 Bible
//determine the number of buttons and titles to the array
sectionNames = new Array("Carshow","More Cars","My Web Sites");
sectionCount = sectionNames.length;
//space between buttons
menuItemSpacing = 10;
for(i=1;i<=sectionCount;i++){
	       _root.menu.menuItemBase.duplicateMovieClip("menuItem_"+i, i);
	       _root.menu["menuItem_"+i].labelName = sectionNames[i-1];
	       if(i != 1){
		          _root.menu["menuItem_"+i]._y = _root.menu["menuItem_"+(i-1)]._y +_root.menu["menuItem_"+(i-1)]._height + menuItemSpacing;
      	}
    }
     _root.menu.menuItemBase._visible = false;

     function checkButtons(){
        	for(i=1;i<=_root.sectionCount;i++){
		       currentItem = "menuItem_" + i;
		       if(currentItem != _root.activeItem){
			     _root.menu["menuItem_" + i].gotoAndStop(1);
		       }
	    }
}
To change the menu just add new titles into the array separated by a comma.

Setting the stage

We need several items: buttons for going to the next and previous slide, main menu, and a button for the automatic slideshow. Further we need buttons for thumbnails. A complete picture of a frame is shown in the figure.

stage

Thumbnail buttons: We create an invisible button, which only shows the area for the mouse but is otherwise empty. Instances of this button are used for opening slides by clicking on the thumbnail images. You do not have to name them but I did it for clarity to know which button belongs to which nailholder. Then we need movieclips to hold our images:
for showing individual slides (slideHolder) and for the thumbnails (nailHolder).
You have to name all of them. Next we need dynamic textboxes for the slide descriptions and instructions.

The Timeline

In this figure you can see the movie timeline. Use folders for objects which are similar as shown here.

timeline

Actionscript: frame 1, part 1

Next we need to add some actionscript to give functionality to buttons and frames. We add actionscript to get the current date and add a function here to clear the automatic advancement of slides (function clearEverything). The automatic slide advancement is discussed later.

//creating the date object to see the day, month, year and time
myDate = new Date();
myArray = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
thisDate = myDate.getDay();
monthDate = myDate.getMonth()+1;
dateTextField = "Today is "+ myArray[thisDate] +" "+ (monthDate + " - " +myDate.getDate() + " - " +myDate.getFullYear());

function clearEverything() {
	for (timer=1;timer <= 10;timer++) {
		clearInterval(myTimer +timer);
	}
}

The Preloader

Most users still have modems so we have to preload the slides to have them ready when buttons are pushed. We make a preload function here

//function to preload slides
function loadAll(firstSlide,lastSlide,slideName,introSlide){
   for (j=1;j<=lastSlide;j++) {
//use duplicateMovieClip here instaed of createEmptyMovieClip
    duplicateMovieClip (_root.slideHolder, "pic_"+j, j);  
//make the slides invisible not to see the loading
	setProperty ("pic_"+j, _alpha, (0));
    loadMovie(slideName+j+".jpg","pic_"+j);
//load slides into slideholder_1 and make it invisible not to see the loading
	loadMovie(slideName+j+".jpg","slideHolder_1");
setProperty("slideHolder_1",_alpha, (0));  
//here we load an introduction slide
	loadMovie(introSlide,"slideHolder");
   }
}
To monitor the loading we attach the following script to slideHolder_1.
onClipEvent(enterFrame){
    if(this._url != _root._url && !loaded) {
        // calculate size of pics in kilobytes
        var kilobytes = Math.ceil(this.getBytesTotal()/1024);
        // calculate percent loaded
        var percentLoaded = Math.ceil((this.getBytesLoaded()/this.getBytesTotal()) * 100);
        // show loading message
        _root.percentOutput = "loading " + percentLoaded + "% of " + kilobytes + "k";
        //show text loading slides
        _root.loadText.gotoAndPlay("play");
		if(percentLoaded == 100){
             //loading terminated
             loaded = true; 
             _root.percentOutput = "Ready";
             _root.loadText.gotoAndStop("stop");
        }
    }
}

Actionscript: frame 1, next Slide function

We now create a function to go manually through the slides.

//function to go to the next slide.
//k is a global variable here and set to "0" so that first slide
//will be in fact the number for first slide.
//The number for the first slide can be different from 1.
var k = 0;
function nextSlide(firstSlide,lastSlide,slideName,slideText) {
	_root.clearEverything();
	_root.loadText.gotoAndStop("stop");
	percentOutput = "";
	//k is incremented by 1 to set to value of next slide.
	k = k+1;
	//i is the actual slide number.
	i = (firstSlide - 1) + k;
    //function to load text, when html you can place links
    //var newText to load corresponding text into textbox.
    newText = (slideText + i + ".txt");
	loadVarsText = new loadVars();
	loadVarsText.load(newText);
	loadVarsText.onLoad = function(success) {
		if(success) {
			scroller.html = true;
			scroller.htmlText = this.myText;
		}else{
			trace("not loaded");
		}
	}  
	// if statements to hide next or previous button
    // and to load the pics
	if (i == firstSlide) {
		_root.leftBut._visible = false;
		i = firstSlide;
 _root.slideHolder.loadMovie(slideName + i + ".jpg");
		_root.newText;		
	}
	if (i == lastSlide) {
	_root.rightBut._visible = false;
		i = lastSlide;
 _root.slideHolder.loadMovie(slideName + i + ".jpg");
		_root.newText;
	} else if (i !== firstSlide && i !== lastSlide) {
		_root.rightBut._visible = true;
		_root.leftBut._visible = true;
		i = (i+1) -firstSlide;
	 _root.slideHolder.loadMovie(slideName + i + ".jpg");
		_root.newText;		
	}
}

Actionscript: frame 1, previous Slide function

Next we create a function to go manually to a previous slide.

//function to go to the previous slide
function previousSlide (firstSlide,lastSlide,slideName,slideText) {
   	// here we decrement i by 1 to go to previous slide
   	i = i-1;
   	_root.slideHolder.loadMovie(slideName + i + ".jpg");
    newText = (slideText + i + ".txt");
   	loadVarsText = new loadVars();
   	loadVarsText.load(newText);
   	loadVarsText.onLoad = function(success) {
     		if(success) {
    			scroller.html = true;
	    		scroller.htmlText = this.myText;
    		}else{
    			trace("not loaded");
    		}
  	}
  	if (i == firstSlide) {
    		_root.leftBut._visible = false;
  	}else{
    		_root.leftBut._visible = true;
  	}
  	if (i == lastSlide) {
    	_root.rightBut._visible = false;
  		k = 1;
  	}else{
    		_root.rightBut._visible = true;
  	}
}

Actionscript: frame 1, Loading thumbnails and function to load slides

The next two functions are to load the thumbnails and to make the thumbnail buttons functional (function showSlide).

//function to load the thumbnails
function preView (firstSlide,lastSlide,nailName) {
  	clearEverything();
	 //loading the thumbnails
  	while (firstSlide <= lastSlide) {
     		_root["nailHolder_" + firstSlide].loadMovie(nailName + firstSlide +".jpg");
    		firstSlide++;
    	}
  	unloadMovie(slideHolder);
 	// load text for preview
 	loadVarsText = new loadVars();
 	loadVarsText.load("preview.txt");
 	loadVarsText.onLoad = function(success) {
  		if(success) {
   			headline.html = true;
   			headline.htmlText = this.headText;
  		}else{
   			trace("text not loaded");
  		}
 	}
}
//function for each thumbnail button to load slide into slideholder.
//This function is attached to thumbnail buttons. Each slidenumber has
//to be set individually. See the invbox actions for details.
function showSlide (slideNumber,slideName,slideText,lastSlide) {
  	clearEverything();
  	_root.slideHolder.unloadMovie();
  	_root.slideHolder.loadMovie(slideName + slideNumber + ".jpg");
  	newText = (slideText + slideNumber + ".txt");
  	loadVarsText = new loadVars();
  	loadVarsText.load(newText);
  	loadVarsText.onLoad = function(success) {
    		if(success) {
     			scroller.html = true;
	     		scroller.htmlText = this.myText;
   		}else{
	     		trace("not loaded");
   		}
  	}
 	//This is to hide the slideshow right and left buttons.
 	_root.rightBut._visible = false;
 	_root.leftBut._visible = false;
}

Actionscript: frame 2

In frame 2 we put a function to load text for the slides. We could have put this function into frame 1 as well.

stop();

//function to load slidetext
function loadSlidetext(slideName,i) {
newText = (slideName + i + ".txt");
	loadVarsText = new loadVars();
	loadVarsText.load(newText);
	loadVarsText.onLoad = function(success) {
		if(success) {
			scroller.html = true;
			scroller.htmlText = this.myText;
		}else{
			trace("not loaded");
		}
	}
}
//calling a url for an external mp3 file to play music
mySound = new Sound();
mySound.loadSound("http://geocities.com/jamit_5000/audio/lanier3.mp3",true);

Actionscript: slideshow frame

In the actual slideshow frames (4 and 5) we load text into the textbox to give instructions to the viewer and also hide the left previous button at start. We add an external script, which contains instructions for preloading the images and for the automatic slide show.

stop();

//this loads the dynamic textbox with the initial text at start
loadVarsText = new loadVars();
loadVarsText.load("preview.txt");
loadVarsText.onLoad = function(success) {
	if (success) {
		_root.headline.html = true;
		_root.headline.htmlText = this.headText;
	}else{
		trace("text not loaded,try again")
	}
}

//this will hide the previous button at start
_root.leftBut._visible = false;

#include "frame1.txt"

Actionscript: last frame

In order to remove previously loaded slides we have to remove the slideholders created with ´duplicateMovieClip()´. So we create a frame after all the slide show frames with the following script, which also clears Interval and unloads slides.

function removeClips () {
     for (j=1;j<=10;j++) {
      _root["pic_"+j].removeMovieClip();
     }
}
removeClips();
_root.clearEverything();
_root.slideHolder.unloadMovie();
//go back to the actionscript frames and automatically to the main menu
gotoAndPlay(1);

#include "frame4.txt"

Here we have an external script for a slide frame. You will find a number of external scripts, which contain functions, where we can change arguments. To load the scripts into the swf file open the fla file and without changing anything export the swf file. The moveSlide function can be extended up to the number of slides we want to show. Just add more of the individual subfunctions for each slide. The clearInterval function we have encountered in a previous frame will completely inactivate any setInterval command, in particular of the last slide. However, for each slide frame we have to make this function new and give it a new name. We also create an introductory slide to start the slideshow. The delay has to be set in equal time intervals such as 1000, 2000, 3000 or 2000, 4000, 6000 as shown here.

//will load the thumbnails
preView(1,3,"nail_");
//preloading slides
_root.loadAll(1,3,"slidea_","introslide.jpg");

//automatic slide show using setInterval and clearInterval
function moveSlide_1() {
	//unloading the textfield
	percentOutput = "";
	slide_1 = new Object();
	slide_1.interval = function() {
		_root.slideHolder.loadMovie("slidea_1.jpg");
		loadSlidetext("slidea_",1);
	}
	myTimer1 = setInterval( slide_1, "interval", 2000); 
	slide_2 = new Object();
	slide_2.interval = function() {
		clearInterval(myTimer1);
		_root.slideHolder.loadMovie("slidea_2.jpg");
		loadSlidetext("slidea_",2);
	}
	myTimer2 = setInterval( slide_2, "interval", 4000); 
	slide_3 = new Object();
	slide_3.interval = function() {
		clearInterval(myTimer2);
		_root.slideHolder.loadMovie("slidea_3.jpg");
		loadSlidetext("slidea_",3);
	}
	myTimer3 = setInterval( slide_3, "interval", 6000); 
}

Adding function to buttons

We now will add functions to the individual buttons. For this check out the actionscript associated with each button. Arguments of button functions can be changed in external scripts for some buttons such as the ´next´ and ´previous´ buttons.

Next button

on (release) {
	nextSlide (1,3,"slidea_","slidea_")
}

Each invisible button will get a function. You can set up the stage for one frameset and then just copy all frames and paste them to have the next slide show frameset, which also copies all the functions associated with buttons. Only the autoshow button function has to be modified.

Example for Invisible buttons

on (release) {
	showSlide(7,"slidea_","slidea_");
}

Example for autoshow button

on (release) {
	moveSlide_1();
}

Conclusion

I did not arrange slides and texts into folders because of publishing the tutorial, which I would however recommend. The slides should not be saved as ´progressive´. When changing any function arguments in the external files do not forget to export the movie again to load the changes into the main movie. If you find problems please e-mail me and also if you have suggestions to improve the slide show.