04.20.2009
Here’s a Flash MVC slideshow in ActionScript 3. My goal here was to keep the code clean while adding the features the customer wanted: unobtrusive controls, drop shadows, optional info text, and smooth cross-fades between images. The MVC pattern makes keeping the code organized easy while TweenLite makes all the transitions super easy to manage.
See it in action at poseygirlflowers. Or download the source Flash files.
I’ve posted some of the code below. There are several additional classes you’ll need + the .Fla in the .zip archive.
SlideModel.as
package slideshow
{
import flash.events.Event;
public class SlideshowModel extends Model
{
public var images:XMLList;
public var currentImage:XML;
public var currentTitle:String;
public var currentFile:String;
public function SlideshowModel()
{
}
override protected function updateData():void
{
currentImage = images[currentIndex];
totalItems = images.length();
currentTitle = currentImage.title;
currentFile = currentImage.file;
}
override protected function dataLoaded(event:Event):void
{
data = new XML(loader.data);
images = data.image;
setCurrentIndex(currentIndex);
}
}
}
SlideView.as
package slideshow
{
import flash.display.*;
import flash.events.Event;
import flash.net.URLRequest;
import flash.filters.DropShadowFilter;
import gs.TweenLite;
// only need this for debug:
import flash.text.*;
public class SlideshowView extends View
{
private var loader:Loader;
private var bmp:Bitmap;
public var container:Sprite;
public var buttonsMc:MovieClip;
// store a reference to the _controller:
private var _controller:SlideshowController;
private var stageWidth:Number = 580;
private var stageHeight:Number = 520;
// we will only allow the user to getNext/Prev image if we
// are not currentlyanimating a transition between 2 images:
private var isAnimating:Boolean;
private var baseURL:String = "http://www.stevenloe.com/projects/flash/mvc-slideshow/";
public function SlideshowView(c:Sprite)
{
container = c;
container.buttonMode = true;
bmp = new Bitmap();
loader = new Loader();
container.addChild(bmp);
container.addChild(loader);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);
}
override public function update(event:Event = null):void
{
if(loader.width > 0)
{
container.addChild(bmp);
bmp.alpha = 1;
bmp.x = loader.x;
bmp.y = loader.y;
bmp.bitmapData = new BitmapData(loader.content.width, loader.content.height);
bmp.bitmapData.draw(loader);
}
trace("IMAGE URL : " + baseURL + model.currentFile );
loader.load(new URLRequest(baseURL + model.currentFile));
//display the file name of the image being requested:
//buttonsMc.debug_txt.text = "\nLoad:: File: " + model.currentFile + " " + model.currentIndex;
}
private function imageLoaded(event:Event):void
{
var myDropShadowFilter = new DropShadowFilter (12,45,0x000000,0.5,10,10,1,2,false,false,false);
container.filters = [myDropShadowFilter];
container.addChild(loader);
loader.x = (stageWidth / 2) - (loader.width / 2);
loader.y = (stageHeight / 2) - (loader.height / 2) -30;
loader.alpha = 0;
TweenLite.to(loader,0.7,{alpha:1,onStart:onTweenStart, onComplete:onTweenComplete});
TweenLite.to(bmp, 0.7, {alpha:0});
_controller.startTimer();
//display request success:
//buttonsMc.debug_txt.text += "\nLoaded!:: Index: " + model.currentIndex;
}
public function getIsAnimating():Boolean
{
return isAnimating;
}
// set a flag that will allow us to ignore user input while
// an animation is in progress
private function onTweenStart():void
{
isAnimating = true;
}
private function onTweenComplete():void
{
isAnimating = false;
}
// show/hide the play & pause buttons to reflect the action currently avalible to the user:
// the two buttons are stacked on the stage
public function showButton(b:String):void
{
if(b == "play")
{
buttonsMc.play_btn.visible = true;
buttonsMc.pause_btn.visible = false;
}
else
{
buttonsMc.play_btn.visible = false;
buttonsMc.pause_btn.visible = true;
}
}
// pass in a reference to the controller so that it can call getIsAnimating:
public function setControllerReference(c:SlideshowController):void
{
_controller = c;
}
// pass in a reference to the MC that contains our buttons on stage
public function setButtonsReference(b:MovieClip):void
{
buttonsMc = b;
}
}
}
SlideController.as
package slideshow
{
import flash.display.DisplayObject;
import flash.events.*;
import flash.utils.Timer;
public class SlideshowController extends Controller
{
private var autoPlayEnabled:Boolean = true;
// set time to display each image here:
private var autoPlayTimer = new Timer(7000, 1);
// store a reference to the view:
private var _slideView:SlideshowView;
public function SlideshowController(m:Model)
{
super(m);
autoPlayTimer.addEventListener(TimerEvent.TIMER_COMPLETE, nextItem);
}
public function addNextButton(btn:DisplayObject):void
{
btn.addEventListener(MouseEvent.CLICK, nextItem);
btn.addEventListener(MouseEvent.CLICK, continueShow);
}
public function addPrevButton(btn:DisplayObject):void
{
btn.addEventListener(MouseEvent.CLICK, prevItem);
btn.addEventListener(MouseEvent.CLICK, continueShow);
}
public function addPlayBtn(btn:DisplayObject):void
{
btn.addEventListener(MouseEvent.CLICK, play);
}
public function addPauseBtn(btn:DisplayObject):void
{
btn.addEventListener(MouseEvent.CLICK, pause);
}
// ----- begin slideshow control functions -----
override public function nextItem(event:Event = null):void
{
if(!_slideView.getIsAnimating())
{
model.setCurrentIndex(model.currentIndex +1);
}
}
override public function prevItem(event:Event = null):void
{
if(!_slideView.getIsAnimating())
{
model.setCurrentIndex(model.currentIndex -1);
}
}
private function play(event:Event):void
{
if(!_slideView.getIsAnimating())
{
trace("play");
nextItem();
autoPlayTimer.start();
autoPlayEnabled = true;
_slideView.showButton("pause");
}
}
private function pause(event:Event):void
{
if(!_slideView.getIsAnimating())
{
trace("pause");
autoPlayTimer.stop();
autoPlayEnabled = false;
_slideView.showButton("play");
}
}
// when the user presses Next/Prev we want to reset the timer and start a new timer running
private function continueShow(event:Event):void
{
if(!_slideView.getIsAnimating())
{
trace("pause");
autoPlayTimer.reset();
autoPlayTimer.start();
autoPlayEnabled = true;
_slideView.showButton("pause");
}
}
public function startTimer():void
{
trace("start timer");
if(autoPlayEnabled)
{
autoPlayTimer.start();
trace("START");
}
}
public function setViewReference(v:SlideshowView):void
{
_slideView = v;
}
}
}
Comments
Leave a Reply