You are here : : Home > Free Resources > Flash Tutorials & Resources > Flash & XML Photo Gallery Tutorial |
Basics
Animation & Effects
Actionscript
Miscellaneous
Flash Articles
Free Flash Resources
Other Flash Resources
This tutorial will teach you how to create an XML powered photo gallery in Flash. You will learn about Flash & XML, how to load photos in Flash and finally how to create an awesome gallery with a 3D effect and scrolling thumbnails.
This tutorial consists of three parts:
You can find the source fla at the end of the tutorial.
XML is the abbreviation for Extensible Markup Language. XML is widely used in software and interactive media. What XML does is hold information that describes objects. XML is very much like HTML, where everything is store in tags. The basic syntax of XML is:
<data> your info goes here </data>
The difference of XML from HTML is that in XML you can define your own tags on the fly. If I wanted to define a book, I might have something like this:
<?xml version="1.0" encoding="utf-8" ?>
<book>
<author>
entheosweb
</author>
<title>
programming methodology
</title>
</book>
With flash you can load XML into your application and manipulate the data using the same rules every time, but produce different content each time.
The below diagram explains the process of flash loading XML and spitting out content:
![]() |
The Process of Flash loading XML |
As you can see, your flash application can load different files and output different content with each XML.
Lets looks at a sample XML:
<?xml version="1.0" encoding="utf-8" ?>
<gallery>
<photo>
<url> picture1.png </url>
<title> Birthday </title>
<description> This is a picture at my birthday </description>
</photo>
<photo>
<url> picture2.png </url>
<title> Scenery </title>
<description> I took this picture a long time ago </description>
</photo>
<photo>
<url> picture3.png </url>
<title> Scenery </title>
<description> I took this picture a long time ago </description>
</photo>
</gallery>
Save the xml file as galleryXML.xml, and make sure you put in the same folder as your Flash file.
Now, to have flash load this file, open up your code box in flash and put this code in:
import flash.net.URLLoader;
import flash.net.URLRequest;
var galleryXML:XML;
var xmlLoader:URLLoader;
var xmlRequest:URLRequest;
xmlLoader = new URLLoader();
xmlRequest = new URLRequest('galleryXML.xml');
xmlLoader.load(xmlRequest);
xmlLoader.addEventListener(Event.COMPLETE,onComplete);
function onComplete(e:Event):void
{
galleryXML = new XML(xmlLoader.data);
trace(galleryXML);
}
We need to make use of the event system, because it actually takes a noticeable amount of time to load images into flash, especially with larger images.
Save your flash file in the same directory as the xml file, and if you run that code, you should see your xml output.
The next step is to get specific information about each item in the XML. Change the above trace statement to this:
trace(galleryXML.photo);
you will see that every photo item is output. What we basically did is tell flash to return a list of items of the tag specified. moving a step further:
trace(galleryXML.photo.title);
to access a certain item in the list, use the same method as an Array:
trace(galleryXML.photo.title[0]);
To find out how many items of a specific tag, you can use the length() function.
trace(galleryXML.photo.title.length());
Note : Something to keep in mind is, that the path specified in the swf is not relative to the swf itself, but the swf player, or web page that loads it. In other words, the loaded content is from the path relative to the html page. This is important when incorporating the gallery to your webpage.
This conclude the first part of the tutorial. In the next part, you will learn how to turn your xml into a photo gallery.
Now you will learn how to load photos into your application at run time.
Loading photos is very much like loading an XML. The difference is that you will have to use the Loader class, which can load DisplayObjects.
Find a png or jpeg photo on your computer, and put it in the same directory as your flash file. I have a photo called Garden.jpeg, which I will be using in this example.
To load your image, use the code provided below:
Similar to XML loading, you need an URLRequest object, but instead of using the URLLoader object, we will need the loader object, and add the complete event to its contentLoaderInfo property.
import flash.net.URLRequest;
var imageLoader:Loader;
var imageRequest:URLRequest;
imageLoader = new Loader();
imageRequest = new URLRequest('Garden.jpg');
imageLoader.load(imageRequest);
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,showPic);
function showPic(e:Event):void
{
imageLoader.content.width = 550;
imageLoader.content.height = 400;
addChild(imageLoader.content);
}
Now it's time to load your images from the XML's urls. You already know how to read information from an XML file, but how do we load all these images, when they each have their own loading event? The answer is quite simple: load the images one by one, according the the number of imaged provided in the xml, and push them into an Array When we have reached our last image, we are done and read to display them.
I currently have 3 images in my folder, and changed my xml file accordingly:
<?xml version="1.0" encoding="utf-8" ?>
<gallery>
<photo>
<url> Garden.jpg </url>
<title> Garden </title>
<description> lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem
ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum </description>
</photo>
<photo>
<url> Waterfall.jpg </url>
<title> Garden </title>
<description> lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem
ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum </description>
</photo>
<photo>
<url> Winter Leaves.jpg </url>
<title> Garden </title>
<description> lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem
ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum </description>
</photo>
</gallery>
edit your code form the last tutorial to look like this:
import flash.net.URLLoader;
import flash.net.URLRequest;
var galleryXML:XML;
var xmlLoader:URLLoader;
var xmlRequest:URLRequest;
xmlLoader = new URLLoader();
xmlRequest = new URLRequest('galleryXML.xml');
xmlLoader.load(xmlRequest);
xmlLoader.addEventListener(Event.COMPLETE,onComplete);
function onComplete(e:Event):void
{
galleryXML = new XML(xmlLoader.data);
var imagesList:Array = new Array();
var i:int = galleryXML.photo.length();
while(i--)
{
imagesList.push(String(galleryXML.photo[i].url));
}
}
Once the XML has been loaded, we created an array and put the urls to all the imagesinto an array, so they are easier to work with when you try to load them. Now we want to load these images consecutively. The logic of that is to start loading the next file when the current one is finished loading, and check if it is the last file. If the last file has been reached, we stop and the loading is over. Using this method we can get information quickly to the user.
Note that sometimes an application gets a bad rating because it has a long loading time. This is especially apparent in mobile applications.
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.display.Loader;
import flash.events.Event;
var galleryXML:XML;
var xmlLoader:URLLoader;
var xmlRequest:URLRequest;
xmlLoader = new URLLoader();
xmlRequest = new URLRequest('galleryXML.xml');
var numOfImages:int;
var currImage:int = 0;
var imageLoader:Loader;
var imageRequest:URLRequest;
imageLoader = new Loader();
var imagesList:Array = new Array();
var loadedImages:Array = new Array();
xmlLoader.load(xmlRequest);
xmlLoader.addEventListener(Event.COMPLETE,onComplete);
function onComplete(e:Event):void
{
galleryXML = new XML(xmlLoader.data);
numOfImages = galleryXML.photo.length();
var i:int = numOfImages;
while(i--)
{
imagesList.push(String(galleryXML.photo[i].url));
}
startLoading();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadNext);
}
function startLoading():void{
imageRequest = new URLRequest(imagesList[currImage]);
trace(currImage);
imageLoader.load(imageRequest);
}
function loadNext(e:Event):void
{
if(currImage == numOfImages-1)
{
loadedImages.push(imageLoader.content);
addChild(imageLoader.content);
imageLoader.content.scaleX = imageLoader.content.scaleY = 0.3;
imageLoader.content.x = currImage * 100 - 0;
imageLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE,loadNext);
return;
}
loadedImages.push(imageLoader.content);
addChild(imageLoader.content);
imageLoader.content.scaleX = imageLoader.content.scaleY = 0.3;
imageLoader.content.x = currImage * 100 - 0;
currImage++;
imageRequest = new URLRequest(imagesList[currImage]);
trace(currImage);
imageLoader.load(imageRequest);
}
You can even go a step further, and create a class for holding each individual photo. You have now learned how to retrieve information from an xml, and load the appropriate content. In the next part we will cover how to make your loaded images into a real photo gallery.
One thing to keep in mind is, for swfs that load contents, they have follow the path of the webpage that is loading them. In other words, the swf must be in the same folder as the html that loads the swf. For example, a path in the swf is source/code.txt, then that is talking about the path relative to the web page that loads the swf, not the swf it self.
As you can see, the bottom row of pictures scrolls around according to your mouse position, with a nice drag effect. This easily done with some simple acceleration, velocity, and damping math.
The pseudo code goes like this:
velocity += acceleration;
velocity *= damping;
position += velocity;
Using the method above, you can simulate friction/drag very nicely. By limiting the position, you can make sure that the pictures don't go off the screen. By applying damping, you can make the pictures stop gradually when the acceleration is zero.Then we add EventListeners to each of the pictures. When a picture is clicked, we have a big Bitmap Draw it on top.The code below generates a bitmap, then generates 10 Sprites and puts them into a container. Moving a single container is much easier than moving all the pictures.
import flash.display.Sprite;
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.MouseEvent;
var bd:BitmapData = new BitmapData(400,300);
var b:Bitmap = new Bitmap(bd);
b.x = 75;
b.y = 0;
addChild(b);
bd.draw(bd);
var i:int = 10;
var container:Sprite = new Sprite();
while(i--)
{
var rect:Sprite = new Sprite();
rect.graphics.beginFill(0x111111 * Math.random());
rect.graphics.drawRect(0,0,400,300);
rect.x = i * 120;
rect.width = 100;
rect.height = 60;
container.addChild(rect);
rect.addEventListener(MouseEvent.CLICK,draw);
}
addChild(container);
container.y = 325;
addEventListener(Event.ENTER_FRAME,update);
var vel:Number = 0;
var acc:Number = 0;
var damp:Number = 0.95;
function update(e:Event):void
{
acc = 0;
if(mouseX<150)
acc = 0.5;
if(mouseX>400)
acc = -0.5;
vel +=acc;
vel*=damp;
container.x += vel;
if(container.x>0)
container.x = 0;
if(container.x < 550-container.width)
container.x = 550-container.width;
}
function draw(e:MouseEvent):void
{
bd.draw(Sprite(e.currentTarget));
}
Now integrating this idea with your photos is much more easier. First is the loading procedure, then you do the same and scroll you photos at the bottom. An important thing to remember is that you can't add Click events to bitmap. This is why for each Bitmap you need to create another Sprite to contain the bitmap.
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.display.Loader;
var galleryXML:XML;
var xmlLoader:URLLoader;
var xmlRequest:URLRequest;
xmlLoader = new URLLoader();
xmlRequest = new URLRequest('galleryXML.xml');
var numOfImages:int;
var currImage:int = 0;
var imageLoader:Loader;
var imageRequest:URLRequest;
imageLoader = new Loader();
var imagesList:Array = new Array();
var loadedImages:Array = new Array();
xmlLoader.load(xmlRequest);
xmlLoader.addEventListener(Event.COMPLETE,onComplete);
function onComplete(e:Event):void
{
galleryXML = new XML(xmlLoader.data);
numOfImages = galleryXML.photo.length();
var i:int = numOfImages;
while(i--)
{
imagesList.push(String(galleryXML.photo[i].url));
}
startLoading();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadNext);
}
function startLoading():void{
imageRequest = new URLRequest(imagesList[currImage]);
imageLoader.load(imageRequest);
}
function loadNext(e:Event):void
{
if(currImage == numOfImages-1)
{
loadedImages.push(imageLoader.content);
imageLoader.contentLoaderInfo.removeEventListener
(Event.COMPLETE,loadNext);
var i:int = galleryXML.photo.length();
container = new Sprite();
while(i--)
{
var rect:Bitmap = loadedImages[i];
var bitmapCont:Sprite = new Sprite();
bitmapCont.addChild(rect);
container.addChild(bitmapCont);
bitmapCont.x = i * 120;
bitmapCont.width = 100;
bitmapCont.height = 60;
bitmapCont.addEventListener(MouseEvent.CLICK,draw);
bitmapCont.addEventListener(MouseEvent.MOUSE_OVER,overFunc);
bitmapCont.addEventListener(MouseEvent.MOUSE_OUT,outFunc);
}
addChild(container);
container.y = 325;
addEventListener(Event.ENTER_FRAME,update);
return;
}
loadedImages.push(imageLoader.content);
currImage++;
imageRequest = new URLRequest(imagesList[currImage]);
imageLoader.load(imageRequest);
}
function overFunc(e:Event):void
{
e.currentTarget.width = 110;
e.currentTarget.height = 70;
}
function outFunc(e:Event):void
{
e.currentTarget.width = 100;
e.currentTarget.height = 60;
}
import flash.display.Sprite;
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.MouseEvent;
var bd:BitmapData = new BitmapData(1022,767);
var b:Bitmap = new Bitmap(bd);
b.x = 75;
b.y = 15;
b.width = 400;
b.height = 300;
addChild(b);
var container:Sprite
var vel:Number = 0;
var acc:Number = 0;
var damp:Number = 0.95;
function update(e:Event):void
{
acc = 0;
if(mouseX<150)
acc = - - - -0.5;
if(mouseX>400)
acc = - - -0.5;
vel +=acc;
vel*=damp;
container.x += vel;
if(container.x>0)
container.x = 0;
if(container.x < 550-container.width)
container.x = 550-container.width;
}
function draw(e:MouseEvent):void
{
bd.draw(Sprite(e.currentTarget));
}
You might be wondering why you can't add Click events to Bitmap's. The diagram belows shows why Bitmaps are not eligible for Click events.
var gfilter:GlowFilter = new GlowFilter(0,1,10,10);
this.filters = [gfilter];
this.rotationY = - 20;
this.x = 40;
We hope you enjoyed this tutorial and learned something new and interesting! Join us on Facebook & keep updated with more awesome tutorials from EntheosWeb!
No portion of these materials may be reproduced in any manner whatsoever, without the express written consent of Entheos. Any unauthorized use, sharing, reproduction or distribution of these materials by any means, electronic, mechanical, or otherwise is strictly prohibited.