Skip to content


Image Gallery – Part I – The Scrolling Menu

So for my image gallery project I wrote up some classes that will generate a scrolling menu and center the menu at the bottom of my page. I have made it so the menu will accept variable widths of images (I honestly haven’t tested this, but I am 98% confident it will work), but a fixed height of 100px, the actual image is like 140px, this is so it will create a scrolling animation on MouseOver. So here is Part I of the Flash Image Gallery, the Scrolling Menu, just click the black rectangles for directional navigation:

First thing, is a class to preload any images, called this LoadImage.as

package {
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.events.IEventDispatcher;
    import flash.net.URLRequest;

    public class LoadImage extends Sprite {
        private var url:String;
		private var imageHolder:Sprite;
		public var LoadImageArray:Array = new Array();
		public var bits:Number;
		public var bitsLoaded:Number;
		public var totalBits:Number;
		private var loader:Loader;

		private var completeStatus:Boolean = false;

        public function LoadImage(url:String) {
			var loader:Loader = new Loader();
            configureListeners(loader.contentLoaderInfo);

            var request:URLRequest = new URLRequest( url );
            loader.load(request);

			imageHolder = new Sprite();
			addChild ( imageHolder );
			imageHolder.addChild(loader);
        }

        private function configureListeners(dispatcher:IEventDispatcher):void {
			dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			addEventListener(Event.COMPLETE, completeHandler);

        }

        private function completeHandler(event:Event):void {
			removeEventListener(Event.COMPLETE, completeHandler);
			setComplete();
		}

		public function setComplete()
		{
			completeStatus = true;
			return ( completeStatus );
		}

		public function getBits()
		{
			return ( bits );
		}

		public function getBitsLoaded()
		{
			return ( bitsLoaded );
		}

		public function w()
		{
			return this.width;
		}

        private function progressHandler(event:ProgressEvent):void {
			bitsLoaded = event.bytesLoaded;
			bits = event.bytesTotal;
        }
    }
}

A class for my Thumbnail Images, called this Thumbnail.as

package
{
	import flash.display.Sprite;
	import flash.events.Event;

	public class Thumbnail extends Sprite
	{
		private var thumb:LoadImage;
		public var myWidth:Number;
		public var myId:Number;

		public function Thumbnail(img:String, id:Number)
		{
			// set this id
			myId = id;

			// load in the image
			thumb = new LoadImage( img );
			addChild ( thumb );

			// check the image load
			addEventListener ( Event.ENTER_FRAME, checkLoad );
		}

		private function checkLoad ( e:Event ):void
		{
			if ( thumb.setComplete() && thumb.w() > 0)
			{
				// remove the listener
				removeEventListener ( Event.ENTER_FRAME, checkLoad );

				// get the width
				myWidth = thumb.w();
			}
		}
	}
}

Lastly, the Main Document Class, ImageGallery.as

package
{
	import flash.display.Sprite;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import caurina.transitions.*;

	public class ImageGallery extends Sprite
	{
		private var ThumbArray:Array;
		private var tobj:Array; // thumb object array
		private var thumbMargin:Number = 5;
		private var ThumbNavigation:Sprite; // this is to hold all the thumbnails
		private var incrementArr:Array;
		private var VisibleThumbnails:Number = 4; // this will set the number of thumbnails that will be visible.
		private var MaskWidth:Number;
		private var myMask:Shape;
		private var maskHeight:Number = 100;
		private var nb:Sprite;
		private var bb:Sprite;
		private var nbs:Shape; // next button
		private var bbs:Shape; // back button
		private var CurrentIndex:Number = 0;
		private var ButtonIndex:Number;
		private var ButtonCounter:Number = 0;
		private var beginPoint:Number;
		private var endPoint:Number;
		private var destPoint:Number;
		private var ThumbNavigationOffset:Number;

		public function ImageGallery()
		{
			init();

			ButtonIndex = VisibleThumbnails;
		}

		private function init():void
		{
			// the holder movie to hold all the thumbnail images
			ThumbNavigation = new Sprite();
			addChild ( ThumbNavigation );
			// put it off the stage
			ThumbNavigation.y = stage.stageHeight + maskHeight;

			// the array of the thumbnail images
			ThumbArray = new Array();
			ThumbArray[0] = "http://manewc.com/projects/flash/i/imagegallery/avon0.jpg";
			ThumbArray[1] = "http://manewc.com/projects/flash/i/imagegallery/avon1.jpg";
			ThumbArray[2] = "http://manewc.com/projects/flash/i/imagegallery/avon2.jpg";
			ThumbArray[3] = "http://manewc.com/projects/flash/i/imagegallery/avon3.jpg";
			ThumbArray[4] = "http://manewc.com/projects/flash/i/imagegallery/avon4.jpg";
			ThumbArray[5] = "http://manewc.com/projects/flash/i/imagegallery/avon5.jpg";
			ThumbArray[6] = "http://manewc.com/projects/flash/i/imagegallery/avon6.jpg";
			ThumbArray[7] = "http://manewc.com/projects/flash/i/imagegallery/avon7.jpg";
			ThumbArray[8] = "http://manewc.com/projects/flash/i/imagegallery/avon8.jpg";
			ThumbArray[9] = "http://manewc.com/projects/flash/i/imagegallery/avon9.jpg";

			// create the thumbnails
			tobj = new Array;

			for ( var c:uint = 0; c < ThumbArray.length; c++ )
			{
				// create a thumbnail image
				tobj.push ( new Thumbnail( ThumbArray[c], c ) );
			}

			// set the event to make sure all images are loaded
			addEventListener ( Event.ENTER_FRAME, checkLoadedThumb );
		}

		private function checkLoadedThumb ( e:Event ):void
		{
			var loadCounter:Number = 0;

			for ( var d:uint = 0; d < ThumbArray.length; d++ )
			{
				if ( tobj[d].myWidth > 0 )
				{
					loadCounter++;
				}
			}

			if ( loadCounter == ThumbArray.length )
			{
				removeEventListener ( Event.ENTER_FRAME, checkLoadedThumb );

				// position the thumbnails
				positionThumbs();
			}
		}

		private function positionThumbs():void
		{
			var totalWidth:Number = 0;
			incrementArr = new Array();

			for ( var v:uint = 0; v < ThumbArray.length; v++ )
			{
				tobj[v].x = totalWidth;
				tobj[v].alpha = 0;

				// set the increments for each slide position when moving left to right
				incrementArr.push ( totalWidth );

				trace ( incrementArr[v] );
				// check for the width of the mask to go over thumbnail navigation
				if ( v == VisibleThumbnails )
				{
					MaskWidth = totalWidth;

					// create the mask
					CreateThumbnailMask();
				}

				totalWidth += thumbMargin + tobj[v].myWidth;
				// add the thumbnail to the stage
				ThumbNavigation.addChild ( tobj[v] );

				// thumbnail is alpha 0, let's fade it up to 80%
				Tweener.addTween(tobj[v], {alpha: .8, time:.8, transition:"easeOut"});

				// add the mouseevents
				tobj[v].addEventListener ( MouseEvent.MOUSE_OVER, ThumbOver );
				tobj[v].addEventListener ( MouseEvent.MOUSE_DOWN, ThumbDown );
				tobj[v].addEventListener ( MouseEvent.MOUSE_OUT, ThumbOut );
			}
		}

		private function CreateThumbnailMask():void
		{
			// Center the Menu
			ThumbNavigation.x = (stage.stageWidth / 2) - (MaskWidth / 2);
			ThumbNavigationOffset = ThumbNavigation.x;

			// Create the Mask
			myMask = new Shape();
            myMask.graphics.beginFill(0x000000);
            myMask.graphics.drawRect(ThumbNavigation.x, stage.stageHeight-maskHeight, MaskWidth, maskHeight);
            myMask.graphics.endFill();

			addChild ( myMask );

			// set the mask
			ThumbNavigation.mask = myMask;

			// show the Menu on Y axis
			Tweener.addTween(ThumbNavigation,{y:stage.stageHeight-maskHeight, time:.5, transition:"easeOut"});

			// create the next button
			NextButton();

			// create the back button
			BackButton();

			// setupUI;
			SetupUI();
		}

		private function ThumbOver (m:MouseEvent):void
		{
			Tweener.addTween(m.currentTarget, {alpha: 1, time:.8, transition:"easeOutBack"});
			Tweener.addTween(m.currentTarget, {y: -20, time:2, transition:"easeOut"});
		}

		private function ThumbDown (m:MouseEvent):void
		{
			// re initialize the index value
			CurrentIndex = m.currentTarget.myId;
		}

		private function ThumbOut (m:MouseEvent):void
		{
			Tweener.addTween(m.currentTarget, {alpha: .8, time:2, transition:"easeOutBack"});
			Tweener.addTween(m.currentTarget, {y: 0, time:2, transition:"easeOut"});
		}

		private function NextButton():void
		{
			nbs = new Shape();
            nbs.graphics.beginFill(0x000000);
            nbs.graphics.drawRect(stage.stageWidth - 20, stage.stageHeight-maskHeight, 20, maskHeight);
            nbs.graphics.endFill();

			nb = new Sprite();
			nb.name = "nextbutton";
			addChild ( nb );

			nb.addChild ( nbs );

			nb.addEventListener( MouseEvent.MOUSE_DOWN, MoveThumbnails );
		}

		private function BackButton():void
		{
			bbs = new Shape();
            bbs.graphics.beginFill(0x000000);
            //myMask.graphics.lineStyle(1, 0x000000);
            bbs.graphics.drawRect(0, stage.stageHeight-maskHeight, 20, maskHeight);
            bbs.graphics.endFill();

			bb = new Sprite();
			addChild ( bb );
			bb.name = "backbutton";
			bb.addChild ( bbs );

			bb.addEventListener( MouseEvent.MOUSE_DOWN, MoveThumbnails );
		}

		private function MoveThumbnails(m:MouseEvent):void
		{
			// check the current index and slide accordingly
			if ( m.currentTarget.name == "nextbutton" && ButtonIndex < ThumbArray.length )
			{
				nb.removeEventListener( MouseEvent.MOUSE_DOWN, MoveThumbnails );

				ButtonIndex++;

				destPoint = ThumbNavigationOffset - incrementArr[++ButtonCounter];

				Tweener.addTween(ThumbNavigation,{x:destPoint, time:.6, transition:"easeOut", onComplete:EnableButtons("nextbutton")});
			}
			else if ( m.currentTarget.name == "backbutton" && ButtonIndex > 0 )
			{
				bb.removeEventListener( MouseEvent.MOUSE_DOWN, MoveThumbnails );

				ButtonIndex--;

				destPoint = ThumbNavigationOffset - incrementArr[--ButtonCounter];
				Tweener.addTween(ThumbNavigation,{x:destPoint, time:.5, transition:"easeOut", onComplete:EnableButtons("backbutton")});
			}

			SetupUI();
		}

		private function EnableButtons(btnId:String):void
		{
			if ( btnId == "nextbutton" ) nb.addEventListener( MouseEvent.MOUSE_DOWN, MoveThumbnails );
			if ( btnId == "backbutton" ) bb.addEventListener( MouseEvent.MOUSE_DOWN, MoveThumbnails );
		}

		private function SetupUI():void
		{
			// this function is to control the visibility of the next and back buttons
			trace ( "ButtonIndex: " + ButtonIndex + " " + VisibleThumbnails );
			if ( ButtonIndex > VisibleThumbnails )
			{
				Tweener.addTween(bb, {alpha: 1, time:2, transition:"easeOut"});
				// Tweener.addTween(nb, {alpha: 1, time:2, transition:"easeOut"});
				bb.addEventListener( MouseEvent.MOUSE_DOWN, MoveThumbnails );
			}
			else if ( ButtonIndex == VisibleThumbnails )
			{
				Tweener.addTween(bb, {alpha: 0, time:2, transition:"easeOut"});
				bb.removeEventListener( MouseEvent.MOUSE_DOWN, MoveThumbnails );
			}

			if ( ButtonIndex == ThumbArray.length )
			{
				Tweener.addTween(nb, {alpha: 0, time:2, transition:"easeOut"});
				nb.removeEventListener( MouseEvent.MOUSE_DOWN, MoveThumbnails );
			}
			else
			{
				Tweener.addTween(nb, {alpha: 1, time:2, transition:"easeOut"});
				nb.addEventListener( MouseEvent.MOUSE_DOWN, MoveThumbnails );
			}
		}
	}
}

Posted in Actionscript 3, Image Effects, Image Gallery Project, Preloading.


6 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Yaz says

    Nice work, i really like the set up you have here, very dynamic and reuseable.
    i’ve seen another method to this scrolling bar, that actually animated with the mouse positon on the x axis, but this is a great option as well.

    thanks for the Tutorial!

  2. kanu kukreja says

    Hi,
    I’m facing some issues while setting the width and height of thumbnails :(

    I’m doing this:
    LoadImage.as/CompleteHandler
    imageHolder.width = 40;
    imageHolder.height = 40;

    But after adding this image becomes invisible.

    Thanks,
    kanu

  3. admin says

    I have a feeling that the imageHolder should be resized within your main document class file.. although I am not sure how your files are being setup. Can you post your code?

    Thanks, Morgan

  4. kanu kukreja says

    I’m done with this by playing with mask height and width :)
    Thanks
    kanu

  5. xx says

    why “” public var bitsLoaaded:Number; “”

    Loaaded ?? why ?

  6. xx says

    -_ – sorry ~ mistake
    //
    thank you!



Some HTML is OK

or, reply to this post via trackback.