Horizontal Photo Gallery with Hover Zoom Effect

Horizontal Photo Gallery with Hover Zoom Effect

In this tutorial, we’ll see how to build an XML driven Horizontal Photo Gallery with a nice Hover Zoom Effect.

View DemoDownload Source

1. Create a new flash file (Actionscript 3.0) and save it as src.fla.

2. Draw a rectangle the same size as your photos. Convert it to a movie clip with registration point at the top left and give it an instance name of “photo”. Draw an other rectangle a bit larger that will be used as the photo’s frame. Convert it to a movie clip with intance name of “bg”. Place “bg” behind “photo” and with both selected, convert the selection to a movie clip with registration point at the center. Export it for actionscript with a Class name of “Thumb”. Check the src.fla library to see the result.
With the Text tool draw a dynamic Text box and give it an instance name of “currentPhoto”. This text will display the title of the hovered photo.

3. Create an XML file to store the photos’ datas and save it as gallery.xml.

<gallery>
   <photo src="panther.jpg" title="The Panther"/>
   <photo src="lion.jpg" title="The Lion"/>
   <photo src="giraffe.jpg" title="The Giraffe"/>
   <photo src="buffalo.jpg" title="The Buffalo"/>
   <photo src="gazelle.jpg" title="The Gazelle"/>
   <photo src="elephant.jpg" title="The Elephant"/>
   <photo src="zebra.jpg" title="The Zebra"/>
</gallery>

4. Create an “actions” layer. Open the actions panel. We’ll use the Tweenlite engine so first write the following statements in order to use it and the TintPlugin.

import com.greensock.TweenLite;
import com.greensock.plugins.*;
TweenPlugin.activate([TintPlugin]);

5. Next declare the following variables.

var xml:XML;
var photos:Array;
var totalPhotos:Number;
var folder:String = "photos/";
var gallery:Sprite;
var photosLoaded:int=0;

6. Load the XML file by creating a loadXML() function. When the load is complete, it will call the parseXML() function.

function loadXML(file:String):void{
	var xmlLoader:URLLoader = new URLLoader();
	xmlLoader.load(new URLRequest(file));
	xmlLoader.addEventListener(Event.COMPLETE, parseXML);
}

7. Then we need to parse the XML. We set our xml variable to the xml data, get the total amount of photos and call the l loadGallery() function.

function parseXML(e:Event):void{
	xml = new XML(e.target.data);
	totalPhotos = xml.children().length();
	loadGallery();
}

8. Inside the loadGallery() function, we create a “for” statement to loop through the xml datas to create a Loader for each photo. We store the Loader inside our photos Array variable, and add the Event.COMPLETE listener.

function loadGallery():void{
	photos = new Array();
	for(var i:int = 0; i<totalPhotos; i++){
		var loader:Loader = new Loader();
		loader.load(new URLRequest(folder + xml.photo[i].@src));
		photos.push(loader);
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
	}
}

9. The onComplete() function checks whether all photos are loaded. If so, it calls the createThumbs() function.

function onComplete(e:Event):void{
	photosLoaded++;
	if(photosLoaded == totalPhotos){
		createThumbs();
	}
}

10. Inside the createThumbs() function, create a “for” statement to loop through the photos array in order to create the gallery thumbs. For each thumb, scale it down to half size, set its title property, create its bitmap photo and add it to the gallery.
We use Tweenlite to make them appear one after another.
Position the gallery at the center of the stage.

function createThumbs():void{
	gallery = new Sprite();
	addChild(gallery);
	
	for(var i:int = 0; i < photos.length; i++){
		
		var thumb:Thumb = new Thumb();
		thumb.scaleX = thumb.scaleY = .5;
					
		thumb.x = (thumb.width + 5) * i;
		thumb.title =  xml.photo[i].@title;
			
		var bm:Bitmap = new Bitmap();
		bm = Bitmap(photos[i].content);
		bm.smoothing = true;
		thumb.photo.addChild(bm);
		
		gallery.addChild(thumb);
		TweenLite.from(thumb, .5, {scaleX:0,scaleY:0,alpha:0, delay: i*0.2, onComplete:addThumbListeners,onCompleteParams:[thumb]});
		
	}
	gallery.x = stage.stageWidth/2 - gallery.width/2;
	gallery.y = stage.stageHeight/2 - gallery.height/2;
	
}

11. Once the thumbs are fully created, we add to them “MouseEvent.ROLL_OVER” and “MouseEvent.ROLL_OUT” listeners.

function addThumbListeners(thumb:MovieClip):void{
	thumb.addEventListener(MouseEvent.ROLL_OVER, onThumbOver);
	thumb.addEventListener(MouseEvent.ROLL_OUT, onThumbOut);
}

12. The onThumbOver() function scales up the hovered thumb. We add an onUpdate listener that calls the arrangeThumb() function when this event is triggered. It also tints the photo’s frame to black.
Inside the arrangeThumb() function we place the hovered photo above the other when its scale is superior to .6
When its scale is equal to 1, we set the currentPhoto text to the hovered photo title.

function onThumbOver(evt:MouseEvent):void {
	var thumb:MovieClip = MovieClip(evt.target);
	TweenLite.to(thumb,.5,{scaleX:1,scaleY:1,onUpdate:arrangeThumb, onUpdateParams:[thumb]});
	TweenLite.to (thumb.bg, .5, {tint: 0x000000});
}

function arrangeThumb(thumb:MovieClip):void{
	if (thumb.scaleX>.6)
		gallery.addChild(thumb);
	if(thumb.scaleX==1)
		currentPhoto.text = thumb.title;
}

13. The onThumbOut() function scales down the thumb, tints it back to its grey color and set the currentPhoto text to blank.

function onThumbOut(evt:MouseEvent):void {
	var thumb:MovieClip = MovieClip(evt.target);
	TweenLite.to(thumb,.5,{scaleX:.5, scaleY:.5});
	TweenLite.to (thumb.bg, .5, {tint: 0x999999});
	currentPhoto.text = "";
}

Finally don’t forget to call the loadXML() function to make it work.

loadXML("gallery.xml");

Here’s the final code.

import com.greensock.TweenLite;
import com.greensock.plugins.*;
TweenPlugin.activate([TintPlugin]);

var xml:XML;
var photos:Array;
var totalPhotos:Number;
var folder:String = "photos/";
var gallery:Sprite;
var photosLoaded:int=0;

function loadXML(file:String):void{
	var xmlLoader:URLLoader = new URLLoader();
	xmlLoader.load(new URLRequest(file));
	xmlLoader.addEventListener(Event.COMPLETE, parseXML);
}

function parseXML(e:Event):void{
	xml = new XML(e.target.data);
	totalPhotos = xml.children().length();
	loadGallery();
}

function loadGallery():void{
	photos = new Array();
	for(var i:int = 0; i<totalPhotos; i++){
		var loader:Loader = new Loader();
		loader.load(new URLRequest(folder + xml.photo[i].@src));
		photos.push(loader);
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
	}
}

function onComplete(e:Event):void{
	photosLoaded++;
	if(photosLoaded == totalPhotos){
		createThumbs();
	}
}

function createThumbs():void{
	gallery = new Sprite();
	addChild(gallery);
	
	for(var i:int = 0; i < photos.length; i++){
		
		var thumb:Thumb = new Thumb();
		thumb.scaleX = thumb.scaleY = .5;
					
		thumb.x = (thumb.width + 5) * i;
		thumb.title =  xml.photo[i].@title;
			
		var bm:Bitmap = new Bitmap();
		bm = Bitmap(photos[i].content);
		bm.smoothing = true;
		thumb.photo.addChild(bm);
		
		gallery.addChild(thumb);
		TweenLite.from(thumb, .5, {scaleX:0,scaleY:0,alpha:0, delay: i*0.2, onComplete:addThumbListeners,onCompleteParams:[thumb]});
		
	}
	gallery.x = stage.stageWidth/2 - gallery.width/2;
	gallery.y = stage.stageHeight/2 - gallery.height/2;
	
}

function addThumbListeners(thumb:MovieClip):void{
	thumb.addEventListener(MouseEvent.ROLL_OVER, onThumbOver);
	thumb.addEventListener(MouseEvent.ROLL_OUT, onThumbOut);
}

function onThumbOver(evt:MouseEvent):void {
	var thumb:MovieClip = MovieClip(evt.target);
	TweenLite.to(thumb,.5,{scaleX:1,scaleY:1,onUpdate:arrangeThumb, onUpdateParams:[thumb]});
	TweenLite.to (thumb.bg, .5, {tint: 0x000000});
}

function arrangeThumb(thumb:MovieClip):void{
	if (thumb.scaleX>.6)
		gallery.addChild(thumb);
	if(thumb.scaleX==1)
		currentPhoto.text = thumb.title;
}

function onThumbOut(evt:MouseEvent):void {
	var thumb:MovieClip = MovieClip(evt.target);
	TweenLite.to(thumb,.5,{scaleX:.5, scaleY:.5});
	TweenLite.to (thumb.bg, .5, {tint: 0x999999});
	currentPhoto.text = "";
}

loadXML("gallery.xml");

14 thoughts on “Horizontal Photo Gallery with Hover Zoom Effect

  1. Aleks

    So, I’m working through this…
    And I actually TYPED all the code insted of copy/paste it.. Simply cause I wanna learn it, and see how it’s built up…
    And I’m pretty sure that I’m with no errors in the code, as it says nothing in debugging.. Expect one thing:

    - Call to a possibly undefined method Thumb.

    Now, I’m pretty sure this comes from the fact that I cannot do the following in step 2. No matter how flippin hard I try.

    “Export it for actionscript with a Class name of “Thumb”. Check the src.fla library to see the result.”

    This is simply cause you ask me to Export for ActionScript. And there is just no part in the dropdown menu that says Linkage, to let me export this for ActionScript, and it’s driving me INSANE. In my library however, I have a tab next to the name of the item, that says linkage. However, there is no export for ActionScript option anywhere, and trust me, I’ve looked.
    Ohh, and I use Flash CS5 by the way.

    I’m not completly unknown to Flash, and I have done my fair share of research on the net, on how to do this with CS5, but the closest I get is this:
    http://layersmagazine.com/flash-attaching-movieclips-actionscript.html
    And Step 5… But no dice! I just can’t find the flipping “linkage” option from any dropdown menu what so ever..

    Any help would be GREATLY appreciated, as I wanna use something like this on a school assignment.
    And a quick answer would definetly help me along quite well.. :)

  2. paulo

    hey aLEKS i NEED ur HELP man !!
    where did you find that export to actionscript and the thing in step 5 THNX ..

  3. paulo

    Fonts should be embedded for any text that may be edited at runtime, other than text with the “Use Device Fonts” setting. Use the Text > Font Embedding command to embed fonts.
    Error #2044: Unhandled ioError:. text=Error #2032: Stream Error. URL: file:///C|/Users/JOHN/Documents/phci/gallery.xml
    at src_fla::MainTimeline/loadXML()
    at src_fla::MainTimeline/frame1()

    what should i do with this

  4. Lise

    Hei Aleks,
    I got the same error with flash cs4, because i can’t follow step 2.
    Can you tell me how you have solved it?

    Thank you !

  5. Pingback: Flash Tutorial : Horizontal Photo Gallery with Hover Zoom Effect : All CG Tutorials

  6. Sunny

    What are we doing with “Thumbs” symbol after we exported it in the ActionScript? It is deleted from the scene in the source file, but where is that explanation in the description? This masage shows up when I export Thumb class:
    “A definition for this class could not be found in the classpath, so one will be automatically generated in the SWF file open export”. What does the massage means?
    Thank`s in advance

  7. Dan

    Aleks.. its been a bit since I used flash but I believe linkage is found in the button “properties” where you originally set it up to be exported for actionscript. Im gonna start getting back into flash very soon. Thank you for the tutorial.

    Dan G

    Multimedia designer

  8. Lavanya

    I am learning flash through websites where i found this website a helpy hand. Thanks! Plz Update with more sources.

  9. Cristiano

    Hi, How are you ?
    Your site is fantastic!!! Great Job!!!!
    My question is: Can I use the flash code in a Flex 4 project ?

    Best Regards,

    Cristiano

  10. FASI

    JUST I AM LEARNING THE FLASH, THIS IS VERY HELP FULL TO ME, THANKS A LOT I WILL TRY THIS AND ONCE AGAIN I THANKFULL TO YOU.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>