/************************************************************** * This code was created by Choice City WebWorks * * http://ccwebworks.drivehq.com * * ccwebworks@drivehq.com * * February 5, 2008 * **************************************************************/ /* This class implements an image fader in flash. It takes as input a URL pointing to a control XML file which contains information about the images that are being displayed. It also takes as input the sessionID of the calling html file and a pointer to the movie clip to which the fader will be attached. The format of the XML control file is: ... There is no limit to the number of images that can be specified, except that there must be room to place the buttons. The "link" field is optional and if included, will cause the url to be opened in the browser when the image is clicked. The sessionID will be passed by either the GET or POST method to the url when it is called. The code requires the following items to be present in the flash.swf file: button - movie clip has two labeled frames, "selected" and "notSelected" can have a pressOverlay which will be visible whenever the button is pressed. Has a dynamic text field labeled "butNum" which contains the number of the button - will be set automatically by this class. The button can be any size or shape. pauseButton - movie clip has two labeled frames, "pause" and "play". The "pause" frame should display the two-bar pause button while the "play" frame should display the right pointing arrow. Can have a pressOverlay which will be visible whenever the button is pressed. loadingGraph - movie clip displaying the loading graphic. The movie clip should contain another movie clip labeled "loadingAnim" which is a progress bar. The progress bar will be stretched as the images are loaded. mask - movie clip. Just a black rectangle. *see accompanying .fla file for examples* There are a number of constant parameters at the beginning of this code that can be changed to alter the look of the fader, such as how and where the buttons are placed, how quickly the images are scrolled through, the fade rate, etc. Example usage: new flashFader("showcontrol.xml", "sessionId", this); */ import flash.display.*; import mx.controls.UIScrollBar; /****************************************************************************** * Begin flashFader class ******************************************************************************/ class flashFader { // The following set of variables can be changed by the user to affect the // way the flashFader behaves private var SPEED = 8; // number of seconds to display each image private var FADERATE = 1; // duration of fade in seconds private var FRAMERATE=20; // frames per second of base flash movie private var TARGET="_top"; // this constant controls the method used when // linking through to the specified URL. // values are: // "_self" specifies the current frame in the current window. // "_blank" specifies a new window. // "_parent" specifies the parent of the current frame. // "_top" specifies the top-level frame in the current window private var BUT_RGN_ULX=360; // these constants specifies the upper left corner private var BUT_RGN_ULY=240; // and lower right corner of the area private var BUT_RGN_LRX=650; // designated for holding the select buttons. private var BUT_RGN_LRY=240; // buttons will be spaced evenly through area // use ULX=LRX for a straight vertical line and // ULY=LRY for a straight horizontal line private var BUT_SPACING=1; // set this to 0 to space the buttons evenly // set this to 1 to force fixed spacing private var URLMETHOD="GET"; // method used for passing sid to the link // can be either "GET" or "POST" private var PHOTO_XPOS=450; // const parameter - x offset of photo viewer private var PHOTO_YPOS=10; // const parameter - y offset of photo viewer private var PHOTO_SIZEX=360; // const parameter - size of photo viewer private var PHOTO_SIZEY=480; // const parameter - size of photo viewer // These variables are internal to the flashFader and shouldn't be changed by // the user private var record:Array; // this array holds all of the information about // each image, including the loader, the filename // the link, the button, etc. private var sessionID:String; // passed in session ID from parent private var showparent_mc:MovieClip; // pointer to the parent to which all is attached private var m_photoviewer:MovieClip; // movie clip holds the photo viewer pieces private var m_viewerMask:MovieClip; // mask over photoviewer private var loadedCount=0; // number of images loaded so far private var numImages:Number=0; // number of images in the current show private var loader_listener:Object; // callback for the MovieClipLoader private var textBox:TextField; // holds html text private var textBox1:TextField; // holds html text private var textBox2:TextField; // holds html text private var defaultFormat:TextFormat;// formatting for text in box private var hoursBut:MovieClip; private var productsBut:MovieClip; private var linksBut:MovieClip; private var scrollBar:UIScrollBar; private var scrollBar1:UIScrollBar; private var scrollBar2:UIScrollBar; /****************************************************************************** * flashFader constructor * ****************************************************************************** * Constructor, this method takes three parameters, xmlpath_str * * (which is the path to the XML file containing the navigation), sid * * (sessionID) and parent_mc (which is a reference to a movie clip/timeline * * where you'll attach your various menu and photo vieweritems) * * It will also build the callback object that responds whenever an image is * * loaded. * ******************************************************************************/ function flashFader(xmlpath_str:String, parent_mc:MovieClip) { // store the parent movie clips for future use this.showparent_mc = parent_mc; this.record = new Array(); this.m_photoviewer = this.showparent_mc.createEmptyMovieClip("photoViewer1",99); this.textBox = this.showparent_mc.createTextField("textBox",59,48,227,386,260); this.textBox1 = this.showparent_mc.createTextField("textBox1",57,48,227,386,260); this.textBox2 = this.showparent_mc.createTextField("textBox2",55,48,227,386,260); this.textBox.multiline = true; this.textBox.wordWrap=true; //this.textBox.embedFonts = true; this.textBox.antiAliasType="advanced"; this.textBox.html = true; this.textBox1.multiline = true; this.textBox1.wordWrap=true; //this.textBox1.embedFonts = true; this.textBox1.antiAliasType="advanced"; this.textBox1.html = true; this.textBox2.multiline = true; this.textBox2.wordWrap=true; //this.textBox2.embedFonts = true; this.textBox2.antiAliasType="advanced"; this.textBox2.html = true; var thisObj = this; this.defaultFormat = new TextFormat(); this.defaultFormat.leading = -2; this.defaultFormat.font = "Arial"; // this.defaultFormat.underline = false; this.textBox.htmlText = ""; this.textBox.selectable=true; this.textBox.setTextFormat(this.defaultFormat); this.textBox1.htmlText = ""; this.textBox1.selectable=true; this.textBox1.setTextFormat(this.defaultFormat); this.textBox1._visible = false; this.textBox2.htmlText = ""; this.textBox2.selectable=true; this.textBox2.setTextFormat(this.defaultFormat); this.textBox2._visible = false; this.scrollBar = this.showparent_mc.createClassObject(mx.controls.UIScrollBar,"mySB",58); this.scrollBar.setScrollTarget(this.textBox); this.scrollBar.setSize(16, this.textBox._height); this.scrollBar.move(this.textBox._x - 16,this.textBox._y); this.scrollBar._visible = false; this.scrollBar1 = this.showparent_mc.createClassObject(mx.controls.UIScrollBar,"mySB1",56); this.scrollBar1.setScrollTarget(this.textBox1); this.scrollBar1.setSize(16, this.textBox1._height); this.scrollBar1.move(this.textBox1._x - 16,this.textBox1._y); this.scrollBar1._visible = false; this.scrollBar2 = this.showparent_mc.createClassObject(mx.controls.UIScrollBar,"mySB2",54); this.scrollBar2.setScrollTarget(this.textBox2); this.scrollBar2.setSize(16, this.textBox2._height); this.scrollBar2.move(this.textBox2._x - 16,this.textBox2._y); this.scrollBar2._visible = false; var loadit_lv = new LoadVars(); loadit_lv.onData = function(src:String):Void { if (src != undefined) { thisObj.textBox.htmlText = src; thisObj.textBox.setTextFormat(thisObj.defaultFormat); if (thisObj.textBox.maxscroll > 1) { thisObj.textBox.scroll = 1; thisObj.scrollBar._visible = true; } else { thisObj.scrollBar._visible = false; } } } loadit_lv.load("details.htm"); var loadit_lv1 = new LoadVars(); loadit_lv1.onData = function(src:String):Void { if (src != undefined) { thisObj.textBox1.htmlText = src; thisObj.textBox1.setTextFormat(thisObj.defaultFormat); } } loadit_lv1.load("products.htm"); var loadit_lv2 = new LoadVars(); loadit_lv2.onData = function(src:String):Void { if (src != undefined) { thisObj.textBox2.htmlText = src; thisObj.textBox2.setTextFormat(thisObj.defaultFormat); } } loadit_lv2.load("links.htm"); var tabFormat:TextFormat = new TextFormat(); tabFormat.size = 14; tabFormat.color = 0x99ff99; tabFormat.font = "Arial"; tabFormat.align = "center"; this.hoursBut = this.showparent_mc.attachMovie("tab","hoursTab",62,{_x:10,_y:225}); this.hoursBut.createTextField("tabName",1,0,88,84,20); this.hoursBut.tabName.multiline = false; this.hoursBut.tabName.wordWrap = false; this.hoursBut.tabName.embedFonts = true; this.hoursBut.tabName.text = "Hours"; this.hoursBut.tabName.setTextFormat(tabFormat); this.hoursBut.tabName._rotation = -90; this.hoursBut.onRelease = function () { thisObj.textBox._visible = true; if (thisObj.textBox.maxscroll > 1) { thisObj.textBox.scroll = 1; thisObj.scrollBar._visible = true; } else { thisObj.scrollBar._visible = false; } thisObj.textBox1._visible = false; thisObj.scrollBar1._visible = false; thisObj.textBox2._visible = false; thisObj.scrollBar2._visible = false; thisObj.productsBut.gotoAndStop("notSelected"); thisObj.linksBut.gotoAndStop("notSelected"); this.gotoAndStop("selected"); } this.hoursBut.tabText._rotation = 5; this.hoursBut.gotoAndStop("selected"); this.productsBut = this.showparent_mc.attachMovie("tab","prodTab",61,{_x:10,_y:312}); this.productsBut.createTextField("tabName",1,0,88,84,20); this.productsBut.tabName.multiline = false; this.productsBut.tabName.wordWrap = false; this.productsBut.tabName.embedFonts = true; this.productsBut.tabName.text = "Products"; this.productsBut.tabName.setTextFormat(tabFormat); this.productsBut.tabName._rotation = -90; this.productsBut.onRelease = function () { thisObj.textBox1._visible = true; if (thisObj.textBox1.maxscroll > 1) { thisObj.textBox1.scroll = 1; thisObj.scrollBar1._visible = true; } else { thisObj.scrollBar1._visible = false; } thisObj.textBox._visible = false; thisObj.scrollBar._visible = false; thisObj.textBox2._visible = false; thisObj.scrollBar2._visible = false; thisObj.hoursBut.gotoAndStop("notSelected"); thisObj.linksBut.gotoAndStop("notSelected"); this.gotoAndStop("selected"); } this.productsBut.tabText._rotation = 5; this.productsBut.gotoAndStop("notSelected"); this.linksBut = this.showparent_mc.attachMovie("tab","linksTab",60,{_x:10,_y:399}); this.linksBut.createTextField("tabName",1,0,88,84,20); this.linksBut.tabName.multiline = false; this.linksBut.tabName.wordWrap = false; this.linksBut.tabName.embedFonts = true; this.linksBut.tabName.text = "Links"; this.linksBut.tabName.setTextFormat(tabFormat); this.linksBut.tabName._rotation = -90; this.linksBut.onRelease = function () { thisObj.textBox2._visible = true; if (thisObj.textBox2.maxscroll > 1) { thisObj.textBox2.scroll = 1; thisObj.scrollBar2._visible = true; } else { thisObj.scrollBar2._visible = false; } thisObj.textBox._visible = false; thisObj.scrollBar._visible = false; thisObj.textBox1._visible = false; thisObj.scrollBar1._visible = false; thisObj.hoursBut.gotoAndStop("notSelected"); thisObj.productsBut.gotoAndStop("notSelected"); this.gotoAndStop("selected"); } this.linksBut.tabText._rotation = 5; this.linksBut.gotoAndStop("notSelected"); // build the callback for when each image is loaded this.loader_listener = new Object(); this.loader_listener.onLoadInit = function(mc:MovieClip) { // after each image is loaded, create a bitmap and attach it to the movie clip mc._visible = false; thisObj.record[thisObj.loadedCount].bitmap = new BitmapData(mc._width, mc._height, false); thisObj.record[thisObj.loadedCount].loaderMC.attachBitmap(thisObj.record[thisObj.loadedCount].bitmap,2,"auto",true); thisObj.record[thisObj.loadedCount].loaderMC._width = thisObj.PHOTO_SIZEX; thisObj.record[thisObj.loadedCount].loaderMC._height = thisObj.PHOTO_SIZEY; thisObj.record[thisObj.loadedCount].bitmap.draw(mc); thisObj.loadedCount += 1; // check if more loaders still to load if (thisObj.loadedCount != thisObj.numImages) { // load the next image thisObj.record[thisObj.loadedCount].loader.loadClip(thisObj.record[thisObj.loadedCount].file, thisObj.record[thisObj.loadedCount].loaderMC.dummyMC); } else { // after all images are loaded and buttons are placed, start the show thisObj.startShow(); } } // end of loader_listener callback // call this class' initXML function which parses the XML navigation file. this.initXML(xmlpath_str); } /****************************************************************************** * initXML function * ****************************************************************************** * This function, initXML, takes a single parameter (xmlpath_str) and * * is responsible for loading and parsing the XML document and * * converting it into an array of objects. * * After a successful load, it will call initViewers to setup the stage * ******************************************************************************/ private function initXML(xmlpath_str:String):Void { // Set a reference to the current class. var thisObj = this; // The XML object which you will use to load and parse the XML navigation file. var setup_xml:XML = new XML(); setup_xml.ignoreWhite = true; // define a function which will be triggered when the XML file has completed loading. setup_xml.onLoad = function(success:Boolean) { /* if the XML file was successfully loaded and parsed, convert it into an array of objects */ if (success) { // first node contains all of the photos and their parameters var shortcut = this.firstChild; var my_loader:Array = new Array(); var my_loaderMC:Array = new Array(); for (var i = 0; i < shortcut.childNodes.length; i++) { my_loader[i] = new MovieClipLoader(); my_loader[i].addListener(thisObj.loader_listener); my_loaderMC[i] = thisObj.m_photoviewer.createEmptyMovieClip("loaderMC"+String(10+thisObj.numImages),(10+thisObj.numImages)); my_loaderMC[i]._alpha=0; my_loaderMC[i].move(0,0); my_loaderMC[i].createEmptyMovieClip("dummyMC",1); thisObj.record.push({file:shortcut.childNodes[i].attributes.file, link:shortcut.childNodes[i].attributes.link, loader:my_loader[i], loaderMC:my_loaderMC[i]}); if (shortcut.childNodes[i].attributes.link != undefined) { thisObj.record[i].loaderMC.onRelease = function () { if (thisObj.sessionID == "") { getURL(thisObj.record[thisObj.m_photoviewer.currentImage].link,thisObj.TARGET); } else { var variable_mc:MovieClip = this.createEmptyMovieClip("vars",this.getNextHighestDepth()); variable_mc.sid = thisObj.sessionID; variable_mc.getURL(thisObj.record[thisObj.m_photoviewer.currentImage].link,thisObj.TARGET,thisObj.URLMETHOD); } } } thisObj.numImages += 1; } // call the flashFader class' initViewer method. thisObj.initViewers(); } }; // load the navigation XML file. setup_xml.load(this.formatString(xmlpath_str)); } /****************************************************************************** * startShow function * ****************************************************************************** * Once all images are loaded and stage is set, turn the playing switch on * ******************************************************************************/ function startShow() { this.m_photoviewer.currentImage=0; } /****************************************************************************** * buildPhotoViewer function * ****************************************************************************** * this function will build the photo viewer, with all of its various parts. * ******************************************************************************/ private function buildPhotoViewer(xpos, ypos, width, height:Number) { var thisObj = this; // move the photo viewer to the desired x,y location this.m_photoviewer._x=xpos; this.m_photoviewer._y=ypos; // create a mask to hide photos that extend beyond viewer this.m_viewerMask = this.showparent_mc.attachMovie("Mask","ViewerMask",100,{_x:xpos, _y:ypos}); this.m_viewerMask._width=width; this.m_viewerMask._height=height; this.m_photoviewer.setMask(this.m_viewerMask); this.m_photoviewer.currentImage = 0; this.m_photoviewer.prevImage = -1; // here is where the bulk of the running show action is performed // on every frame check to see if the correct image is being displayed // possibly advance to the next image and adjust the fade level of the // images this.m_photoviewer.onEnterFrame = function() { this.currentFrame += 1; if ((thisObj.loadedCount >= thisObj.numImages) && (thisObj.numImages > 1)) { // if all of the images are loaded if (this.currentFrame >= (thisObj.SPEED*thisObj.FRAMERATE)) { // if frame number is beyond the end of the current image this.prevImage = this.currentImage; this.currentImage += 1; this.currentFrame = 0; if (this.currentImage == thisObj.numImages) { this.currentImage = 0; } } if (thisObj.record[this.currentImage].loaderMC._alpha < 100) { thisObj.record[this.currentImage].loaderMC._alpha += 100/(thisObj.FADERATE*thisObj.FRAMERATE); } if (thisObj.record[this.prevImage].loaderMC._alpha > 0) { thisObj.record[this.prevImage].loaderMC._alpha -= 100/(thisObj.FADERATE*thisObj.FRAMERATE); } } else { if (thisObj.record[0].loaderMC._alpha < 100) { thisObj.record[0].loaderMC._alpha += 100/(thisObj.FADERATE*thisObj.FRAMERATE); } } } } /****************************************************************************** * initViewers function * ****************************************************************************** * call the build functions then load the first image * ******************************************************************************/ private function initViewers() { var thisObj = this; this.buildPhotoViewer(this.PHOTO_XPOS,this.PHOTO_YPOS,this.PHOTO_SIZEX,this.PHOTO_SIZEY); thisObj.record[0].loader.loadClip(thisObj.record[0].file, thisObj.record[0].loaderMC.dummyMC); } // these functions keep the xml file from being cached so as to allow changes to // appear right away in the users browser private function formatString(url:String):String{ if(isLocalPlayback()){ return url; } var sTimestamp:String = "×tamp=" + new Date().getTime(); return url + "?cachebuster=" + Math.random() + sTimestamp; } private function isLocalPlayback():Boolean{ return _url.indexOf("file") == 0; } }