Create a Responsive Image Scroller in ActionScript 3.0

This tutorial will demonstrate how to create a horizontally scrolling image viewer. It will cover xml parsing, loading and resizing external images, and creating intuitive and responsive scrolling!

Quick Introduction

I’m a firm believer in learning by coding and tinkering. So in this tutorial, I’m stating what to do and then showing the equivalent code; please dig into the code, change things and tinker – I think that’s one of the best ways to learn! I expect that you have a basic understanding of ActionScript already and I won’t explain the fundamentals. I hope the descriptions will be helpful, but if I don’t explain something that you aren’t quite following, feel free to ask about it in the comments.

Step 1: Set Up XML

We’ll want nodes of images included in our xml. Each node will represent an image with attributes. We can add anything we like here, I’ll stick to three attributes to each image node. The ‘src’ of the image (used to load it in), the title and the url we will link to from the scroller. I’ll go ahead and wrap them all within an images node (in case I want to include anything else in the xml later, such as customization options – hint).

Each image node will need a source image, a title and a url. The source (src) will be the image that gets loaded into the scroller, the title will be what we call it and the url will be the url that we load from the scroller when users click on the image (it can be a larger image or even a website). I’ve gotten some images from the envato asset library and resized them to be used as the thumbnails as well. I shrank the thumbnails to fit into a 140px by 105px area, this is not required but will help to optimize the experience since we won’t be loading in huge images. You’ll see soon that any size image will work because we’ll code it to resize any image that loads to fit into the scroller area!

<images>
<image src="images/tn/scottwills_underwater4.jpg" title="Jelly 4" url="images/scottwills_underwater4.jpg" />
<image src="images/tn/scottwills_cat.jpg" title="Cat" url="images/scottwills_cat.jpg" />
<image src="images/tn/scottwills_modern_sculpture.jpg" title="Statue" url="images/scottwills_modern_sculpture.jpg" />
<image src="images/tn/madness_arch3.jpg" title="Arch 3" url="images/madness_arch3.jpg" />
<image src="images/tn/scottwills_penguin.jpg" title="Penguin" url="images/scottwills_penguin.jpg" />
<image src="images/tn/scottwills_horse.jpg" title="Jelly" url="images/scottwills_horse.jpg" />
<image src="images/tn/scottwills_modernsculpture2.jpg" title="Statue 2" url="images/scottwills_modernsculpture2.jpg" />
<image src="images/tn/madness_arch1.jpg" title="Arch 1" url="images/madness_arch1.jpg" />
<image src="images/tn/madness_arch2.jpg" title="Arch 2" url="images/madness_arch2.jpg" />
</images>

Step 2: Set Up Flash

OK, now that we have our xml file finished, let’s get started in Flash. Open Flash and create a new file (ActionScript 3.0). Adjust the stage size to something around 600 wide and 150 tall, set the background to any color you like (I chose a dark color to help the images stand out a bit more – #000033 if you wanna follow along) and step up the frame rate to 30 frames per second to give us smoother animation. Then let’s go ahead and create a new layer calling it “ActionScript”. On the first frame in the timeline click to the actions panel and we’re ready to continue!

Step 3: Load XML

We need to load the information from the xml file (created in step 1) into our Flash file. It’s a pretty simple step, but a foundation which can spring to many other creative applications. In just a few lines of code we initialize a URLLoader, an XML object to hold our data and a string to specify the path to the xml. Then we load the xml through the urlLoader object. That done, we need an Event listener to fire off when the file is fully loaded, we wouldn’t want to start messing with the xml data before it finishes loading. As specified in the docs, the complete event passes the loaded content as a the event target data property, so we access the actual xml as e.target.data and assign it to our xml object.

Let’s go ahead and double check that we’ve set that all up correctly and trace the image nodes of our xml to the output panel.

//load xml
var xmlLoader:URLLoader = new URLLoader();
var xmlData:XML = new XML();
var xmlPath:String = "image-scroller.xml";
xmlLoader.load(new URLRequest(xmlPath));
trace("loading xml from: " + xmlPath);
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);

function LoadXML(e:Event):void {
	trace("xml loading complete");
	xmlData = new XML(e.target.data);
	trace(xmlData.image); //we'll see each image xml element listed in the output panel with this xmlList
}

/*
output window
///////////////
loading xml from: image-scroller.xml
xml loading complete
<image src="images/tn/scottwills_underwater4.jpg" title="Jelly 4" url="images/scottwills_underwater4.jpg"/>
<image src="images/tn/scottwills_cat.jpg" title="Cat" url="images/scottwills_cat.jpg"/>
<image src="images/tn/scottwills_modern_sculpture.jpg" title="Statue" url="images/scottwills_modern_sculpture.jpg"/>
<image src="images/tn/madness_arch3.jpg" title="Arch 3" url="images/madness_arch3.jpg"/>
<image src="images/tn/scottwills_penguin.jpg" title="Penguin" url="images/scottwills_penguin.jpg"/>
<image src="images/tn/scottwills_horse.jpg" title="Jelly" url="images/scottwills_horse.jpg"/>
<image src="images/tn/scottwills_modernsculpture2.jpg" title="Statue 2" url="images/scottwills_modernsculpture2.jpg"/>
<image src="images/tn/madness_arch1.jpg" title="Arch 1" url="images/madness_arch1.jpg"/>
<image src="images/tn/madness_arch2.jpg" title="Arch 2" url="images/madness_arch2.jpg"/>
*/

Step 4: Parse XML

Loading the xml is great, but we also have to read it and let our code know what to do with the data. So rather than just tracing out the xmlList we’ll send it to another function that will take care of creating our scroller. The buildScroller function will accept an XMLList, so we’ll loop through it, creating movie clip objects for each image in the scroller and assigning them properties according to the xml node attributes title, url and src. Later we’ll build out this function to include much more so it will actually do what it is named for and build the scroller!

For now let’s just trace this info to make sure everything is working according to plan. We can even wrap the content buildScroller function with trace statements so we always know where we are.

//load xml
var xmlLoader:URLLoader = new URLLoader();
var xmlData:XML = new XML();
var xmlPath:String = "image-scroller.xml";
xmlLoader.load(new URLRequest(xmlPath));
trace("loading xml from: " + xmlPath);
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);

function LoadXML(e:Event):void {
	trace("xml loading complete");
	xmlData = new XML(e.target.data);
	buildScroller(xmlData.image); //rather than trace the xmlList, we send it to our buildScroller function

}

//build scroller from xml
function buildScroller(imageList:XMLList):void{
	trace("build Scroller");

	for (var item:uint = 0; item < imageList.length(); item++ )  {
		var thisOne:MovieClip = new MovieClip();

		thisOne.itemNum = item;
		thisOne.title = imageList[item].attribute("title");
		thisOne.link = imageList[item].attribute("url");
		thisOne.src = imageList[item].attribute("src");

		trace(thisOne.itemNum, thisOne.title, thisOne.link, thisOne.src);
	}

	trace("termination of build scroller");
}

/*
output
///////
loading xml from: image-scroller.xml
xml loading complete
build Scroller
0 Jelly 4 images/scottwills_underwater4.jpg images/tn/scottwills_underwater4.jpg
1 Cat images/scottwills_cat.jpg images/tn/scottwills_cat.jpg
2 Statue images/scottwills_modern_sculpture.jpg images/tn/scottwills_modern_sculpture.jpg
3 Arch 3 images/madness_arch3.jpg images/tn/madness_arch3.jpg
4 Penguin images/scottwills_penguin.jpg images/tn/scottwills_penguin.jpg
5 Jelly images/scottwills_horse.jpg images/tn/scottwills_horse.jpg
6 Statue 2 images/scottwills_modernsculpture2.jpg images/tn/scottwills_modernsculpture2.jpg
7 Arch 1 images/madness_arch1.jpg images/tn/madness_arch1.jpg
8 Arch 2 images/madness_arch2.jpg images/tn/madness_arch2.jpg
termination of build scroller

*/

Step 5: Build Scroller MovieClip to Contain Each Image

Now that the build scroller function is created and that it creates objects for each node in the xml, let’s add them to the stage!

We’ll begin by creating a scroller MovieClip. This will be the container for all the objects we want to scroll, so each image node will have a movieclip within this scroller object. Let’s go ahead and add it to the stage, then set the y value to 30. We won’t yet see anything on the stage when we test, but we’re about to add items to the scroller for each image in the xmlList.

var scroller:MovieClip = new MovieClip();
this.addChild(scroller);
scroller.y = 30;

Step 6: Adding Items to Scroller

We already have the movie clips created with properties, but we need to create something we can see, so let’s create a box area to actually see these scroller items. Create a blackBox sprite and give it a shape with the graphics api. I’ve decided that I want my standard scroller item to be 140x105px so I’ll create the blackBox to fit that area and I’ll give it a 1px border on all sides. Move it up and to the left one pixel and give it 142×107 dimensions.

We add the blackbox sprite to the thisOne movieClip and also update the x value of the item. Since each will be 140 wide, I’ll add some padding (20) and lay them out horizontally. I’ll update the trace statement to output what is going on here.

var scroller:MovieClip = new MovieClip();
this.addChild(scroller);
scroller.y = 30;
//build scroller from xml
function buildScroller(imageList:XMLList):void{
	trace("build Scroller");
	for (var item:uint = 0; item < imageList.length(); item++ )  {
		var thisOne:MovieClip = new MovieClip();

		//outline
		var blackBox:Sprite = new Sprite();
		blackBox.graphics.beginFill(0xFFFFFF);
		blackBox.graphics.drawRect( -1, -1, 142, 107);
		thisOne.addChild(blackBox);

		thisOne.x = (140 + 20) * item;
		thisOne.itemNum = item;
		thisOne.title = imageList[item].attribute("title");
		thisOne.link = imageList[item].attribute("url");
		thisOne.src = imageList[item].attribute("src");

		trace(thisOne.itemNum, thisOne.title, " added to scroller");

		//add item
		scroller.addChild(thisOne);
	}
	trace("termination of build scroller");
}
/*
output
///////
loading xml from: image-scroller.xml
xml loading complete
build Scroller
0 Jelly 4  added to scroller
1 Cat  added to scroller
2 Statue  added to scroller
3 Arch 3  added to scroller
4 Penguin  added to scroller
5 Jelly  added to scroller
6 Statue 2  added to scroller
7 Arch 1  added to scroller
8 Arch 2  added to scroller
termination of build scroller
*/

Step 7: Adding Click Listener to Items

Alright, this isn’t much yet because it just looks like a bunch of boxes that don’t do anything. Let’s add a listener to these boxes though, so that we can tell that they are each unique items in the scroller. Thinking of the final result, we’ll add a click listener because we want users to be able to click the item in the scroller and go to the link we put in the xml. Let’s make the clip buttonMode true, so that it’s perceived as something that is click-able. Then add an event Listener for the MouseEvent.CLICK. For now we’ll just have it listen for this click event and fire a function to trace the url we’re aiming at.

Through the output we can see that each box has properties sent to it from the xml.

//build scroller from xml
function buildScroller(imageList:XMLList):void{
	trace("build Scroller");
	for (var item:uint = 0; item < imageList.length(); item++ )  {
		var thisOne:MovieClip = new MovieClip();

		//outline
		var blackBox:Sprite = new Sprite();
		blackBox.graphics.beginFill(0xFFFFFF);
		blackBox.graphics.drawRect( -1, -1, 142, 107);
		thisOne.addChild(blackBox);

		thisOne.x = (140 + 20) * item;
		thisOne.itemNum = item;
		thisOne.title = imageList[item].attribute("title");
		thisOne.link = imageList[item].attribute("url");
		thisOne.src = imageList[item].attribute("src");

		//create listeners for this item
		thisOne.buttonMode = true;
		thisOne.addEventListener(MouseEvent.CLICK, clickScrollerItem);

		//add item
		scroller.addChild(thisOne);
	}

	trace("termination of build scroller");
}

function clickScrollerItem(e:MouseEvent):void {
	trace("clicked item " + e.currentTarget.itemNum + " - visit url: " + e.currentTarget.link);
}

/*
output
//////
loading xml from: image-scroller.xml
xml loading complete
build Scroller
termination of build scroller
clicked item 2 - visit url: images/scottwills_modern_sculpture.jpg
clicked item 0 - visit url: images/scottwills_underwater4.jpg
clicked item 1 - visit url: images/scottwills_cat.jpg
clicked item 3 - visit url: images/madness_arch3.jpg
clicked item 1 - visit url: images/scottwills_cat.jpg
*/

Step 8: Adding More Listeners to Scroller Items

Let’s finish off the event listeners! We’ll want to listen to each of these items to know when a user clicks, mouses over and mouses out.

//build scroller from xml
function buildScroller(imageList:XMLList):void{
	trace("build Scroller");
	for (var item:uint = 0; item < imageList.length(); item++ )  {
		var thisOne:MovieClip = new MovieClip();

		//outline
		var blackBox:Sprite = new Sprite();
		blackBox.graphics.beginFill(0xFFFFFF);
		blackBox.graphics.drawRect( -1, -1, 142, 107);
		thisOne.addChild(blackBox);

		thisOne.x = (140 + 20) * item;
		thisOne.itemNum = item;
		thisOne.title = imageList[item].attribute("title");
		thisOne.link = imageList[item].attribute("url");
		thisOne.src = imageList[item].attribute("src");

		//create listeners for this thumb
		thisOne.buttonMode = true;
		thisOne.addEventListener(MouseEvent.CLICK, clickScrollerItem);
		thisOne.addEventListener(MouseEvent.MOUSE_OVER, overScrollerItem);
		thisOne.addEventListener(MouseEvent.MOUSE_OUT, outScrollerItem);

		//add item
		scroller.addChild(thisOne);
	}

	trace("termination of build scroller");
}

function clickScrollerItem(e:MouseEvent):void {
	trace("clicked item " + e.currentTarget.itemNum + " - visit url: " + e.currentTarget.link);
}
function overScrollerItem(e:MouseEvent):void {
	trace("over " + e.currentTarget.title);
}
function outScrollerItem(e:MouseEvent):void {
	trace("out " + e.currentTarget.title);
}
/* output
//////////////
loading xml from: image-scroller.xml
xml loading complete
build Scroller
termination of build scroller
over Jelly 4
out Jelly 4
over Cat
out Cat
over Statue
out Statue
over Arch 3
out Arch 3
over Arch 3
clicked item 3 - visit url: images/madness_arch3.jpg
out Arch 3
over Statue
clicked item 2 - visit url: images/scottwills_modern_sculpture.jpg
out Statue
*/

Step 9: Loading and Adding the Images

Now the part I’m sure you’ve been getting anxious about, let’s get the images loaded into the scroller items so we can see what they are! We’ll do this in the buildScroller function. Right after the blackbox is created and the properties are assigned for the current item let’s also create another sprite to contain the actual image.

We’ll use a loader object and a URLRequest object to handle the loading of the image, which is newly standardized with ActionScript 3. We’ll pass the src of the image to the urlrequest object, then load the urlrequest with our loader object and finally we’ll add the loader to the thisThumb sprite adding that in turn to the thisOne movieClip. Whew.

It’s pretty self explanatory – and in just a couple of lines of code we’ve loaded the src images from our xml into Flash!

function buildScroller(imageList:XMLList):void{
	trace("build Scroller");
	for (var item:uint = 0; item < imageList.length(); item++ )  {
		var thisOne:MovieClip = new MovieClip();

		//outline
		var blackBox:Sprite = new Sprite();
		blackBox.graphics.beginFill(0xFFFFFF);
		blackBox.graphics.drawRect( -1, -1, 142, 107);
		thisOne.addChild(blackBox);

		thisOne.x = (140 + 20) * item;
		thisOne.itemNum = item;
		thisOne.title = imageList[item].attribute("title");
		thisOne.link = imageList[item].attribute("url");
		thisOne.src = imageList[item].attribute("src");

		//image container
		var thisThumb:Sprite = new Sprite();
		//add image
		var ldr:Loader = new Loader();
		var urlReq:URLRequest = new URLRequest(thisOne.src);
		trace("loading thumbnail "+item+" into Scroller: " + thisOne.src);
		ldr.load(urlReq);
		thisThumb.addChild(ldr);
		thisOne.addChild(thisThumb);

		//create listeners for this thumb
		thisOne.buttonMode = true;
		thisOne.addEventListener(MouseEvent.MOUSE_OVER, overScrollerItem);
		thisOne.addEventListener(MouseEvent.MOUSE_OUT, outScrollerItem);
		thisOne.addEventListener(MouseEvent.CLICK, clickScrollerItem);

		//add item
		scroller.addChild(thisOne);
	}

	trace("termination of build scroller");
}

Step 10: Adding Event Listeners to the Image Loading Process

When we load the images, we need to create some event listeners to tell us when the loading is complete. Best practice deal with any errors (in case there is a typo in the path to the image or we don’t have access or something). So just before we load the images let’s add an event listener for the loader’s contentLoaderInfo object for a complete event and also an i/o error. Then we’ll need to create the event handler functions.

For the completeHandler let’s just trace the image title for now, we’ll have to walk up the hierarchy of the event target’s parent’s parent’s title to find it, because of the way we nested our sprite within our scroller item objects (the thisOne Sprite).

trace("loading thumbnail "+item+" into Scroller: " + url);
//assign event listeners for Loader
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
ldr.load(urlReq);
...
function completeHandler(e:Event):void {
	trace("thumbnail complete "+e.target.loader.parent.parent.title);
}
function errorHandler(e:IOErrorEvent):void {
	trace("thumbnail error="+e);
}

Step 11: Tweening the Images

I’m using Tweener for this tutorial, but there are various tweening engines. If you’re not familiar with it

Tweener (caurina.transitions.Tweener) is a Class used to create tweens and other transitions via ActionScript code for projects built on the Flash platform… In layman’s terms, Tweener helps you move things around on the screen using only code, instead of the timeline.

So first go download it from the google code repository (be sure to get the as3 version) unzip it and put the caurina folder into the same directory as your .fla file, then import the code into your project by placing this in the first line of code:

import caurina.transitions.*;

Then let’s have the images fade in once they’re loaded, instead of just popping like they are. First we’ll set the initial alpha value of the scroller item to 0, so it can fade in properly. Then jump back to our complete event listener handler function and add the Tweener code.

thisOne.alpha = 0;
...
function completeHandler(e:Event):void {
	//trace("thumbnail complete "+e.target.loader.parent.parent.title);
	Tweener.addTween(e.target.loader.parent.parent, { alpha:1, time: .5 } );
}

Step 12: Resizing the Images

Now, since I resized all my images and created thumbnails beforehand, this step is not as important, but is still great to include so that in case the dimensions change or I add another image later, the scroller will be able to handle it and resize it. The resize function will scale an image to fit within an area as I have explained before on my blog. Basically though, in the completeHandler we’ll resize the image to fit an area, even if the image is correctly sized, the resizeMe function will still center the image for us.

function completeHandler(e:Event):void {
	//trace("thumbnail complete "+e.target.loader.parent.parent.name);
	//size image into scroller
	resizeMe(e.target.loader.parent, 140, 105, true, true, false);
	Tweener.addTween(e.target.loader.parent.parent, { alpha:1, time: .5 } );
}

//The resizing function
// parameters
// required: mc = the movieClip to resize
// required: maxW = either the size of the box to resize to, or just the maximum desired width
// optional: maxH = if desired resize area is not a square, the maximum desired height. default is to match to maxW (so if you want to resize to 200x200, just send 200 once, or resizeMe(image, 200);)
// optional: constrainProportions = boolean to determine if you want to constrain proportions or skew image. default true.
// optional: centerHor = centers the displayObject in the maxW area. default true.
// optional: centerVert = centers the displayObject in the maxH area. default true.
function resizeMe(mc:DisplayObject, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true, centerHor:Boolean=true, centerVert:Boolean=true):void{
    maxH = maxH == 0 ? maxW : maxH;
    mc.width = maxW;
    mc.height = maxH;
    if (constrainProportions) {
        mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY;
    }
	if (centerHor) {
		mc.x = (maxW - mc.width) / 2;
	}
	if (centerVert){
		mc.y = (maxH - mc.height) / 2;
	}
}

Step 13: Adding Movement

We’ll start by just adding the basics. We want users to be able to intuitively control this scroller, so we’ll use their mouse position as direction only initially. If the mouse is positioned in the left half of the stage we want to move the scroller to the right, so the user moves in the direction they want the scroller to reveal itself. I prefer this to the direct relationship of moving the scroller the same way the mouse goes, but that’s a discussion for another day.

To implement this is pretty simple, we just add an event listener at the end of the buildScroller function, for every time we enter the frame to position the scroller. Then in the handler function we’ll create an if/else statement and set the new speed variable depending on mouse position. If the mouse x position is on the left half of the stage, we want the scroller to move one way and if it is on the right half of the stage we want it to move the other direction. Then we apply this speed to the x position of the scroller container. This is now starting to look like something useful because it is now interactive and responsive!

Essentially all we are doing is moving the scroller container clip to one direction of the other, but we’re doing it every frame, so it animates the position over time. Remember this scroller clip contains all the items we created, so it’s like putting things into a box and moving the box. The items don’t have to be moved, just the container! We move it either 5 pixels to the left or 5 pixels to the left every single frame (this 5 could be anything, I just chose 5 ’cause it looked right). This leaves a lot to be desired, but it’s the first step. We have our scroller moving and have given the end user the power to control this movement!

Notice that we’re using the stage properties to find the stage size even though we set the stage size earlier and know exactly what size it is. This is because it will help the code to be self containing and portable. If we were to use the actual values we would have to remember to update them if we ever changed the scroller size or wanted to use this in a different application. We’ll create more variables soon that will allow us to fully customize the scroll interaction.

scroller.addEventListener(Event.ENTER_FRAME, moveScrollerThumbs);
trace("termination of build scroller");
...
var speed:Number;
function moveScrollerThumbs(e:Event):void {
	if (mouseX < stage.stageWidth/2) { //left half of stage
		speed = 5;
	}
	else { //right half of stage
		speed = -5;
	}
	scroller.x += speed;
}

Step 14: Better Movement – Mouse Limits

You can see above that we still have a way to go with our movement controls of the scroller. There are boundaries to add to the mouse positions that cause the scrolling (we’d like it to only scroll when you are on the stage and over the scroller), limits we’d like to apply to the scroller (so that it doesn’t scroll off the page) and we want to make the scroller speed dynamic.

Let’s start first by adding a statement to check if we are over the scroller. To do this we’ll check the mouseY position, the scroller.y and scroller.height properties. Let’s also add a bit more to the mouseX statements, let’s ensure that it’s a bit more precise and only include the x values from 0 to the center of the stage (stage.stageWidth/2) and from the center to the edge.

function moveScrollerThumbs(e:Event):void {
	if ( mouseY > scroller.y && mouseY < scroller.y + scroller.height) { //vertically over scroller
		if (mouseX < stage.stageWidth/2 && mouseX > 0) { //left half of stage explicitly
			speed = 5;
		}
		else if (mouseX > stage.stageWidth/2 && mouseX < stage.stageWidth) { //right half of stage explicitly
			speed = -5;
		}
		scroller.x += speed;
	}
}

Step 15: Better Movement – Scroller Limits

Now we’ll want to apply boundaries to the scroller itself so that it doesn’t scroll off the page and leave us with a blank stage and a user who doesn’t know or remember which way the images went.

We need to watch the scroller x position and if it goes too far either way reset it to our limit. Remember that the scroller x position is found at its left edge, so when it is at a 0 x position it is flush with the left edge of the stage. So first off if the x position of the scroller is greater than 0 after the speed is calculated and applied, we want to set it back to our limit, 0. This will keep the scroller from moving too far into the stage. We can even add some padding to the stage and since we have the padding between each scroller item of 20, let’s make it consistent. Rather than using 0 here, let’s make it the same 20 value.

We want the scroller to stop moving left once it’s last item is fully on stage. This left limit can be found by finding the width of the scroller and the stage width. If the scroller is moved so far to the left that it’s x position is less than it’s own width (negative) but factor back in the stage width (plus stageWidth) we need to hold it right there. To add the padding on this end we subtract 20.

function moveScrollerThumbs(e:Event):void {
	if ( mouseY > scroller.y && mouseY < scroller.y + scroller.height) {//vertically over scroller
		if (mouseX < stage.stageWidth/2 && mouseX > 0) {//left of stage explicitly
			speed = 5;
		}
		else if (mouseX > stage.stageWidth/2 && mouseX < stage.stageWidth) {//right of stage explicitly
			speed = -5;
		}
		scroller.x += speed;

		//scroller limits
		if (scroller.x < -scroller.width + stage.stageWidth - 20) { //if scroller too far left
			scroller.x = -scroller.width + stage.stageWidth - 20;
		}
		else if (scroller.x > 20) { //if scroller to far right
			scroller.x = 20;
		}
	}
}

Step 16: Dynamic Movement

To make the movement more fluid and dynamic we only need to update two lines of code. You guessed it, the two lines that set the speed need to be adjusted to determine the speed by the distance mouseX is from the center of the stage rather than a flat value of 5. We find the distance the mouse is horizontally from the center axis of the stage (stage.stageWidth/2), and we want the scroller to move to the right if we’re on the left side and vice versa. In both instances we find the negative difference between the two. Then we should scale it down by dividing it by, let’s try 8, because if we don’t, the scroller is way too fast (go ahead, try it).

function moveScrollerThumbs(e:Event):void {
	if ( mouseY > scroller.y && mouseY < scroller.y + scroller.height) {//vertically over scroller
		if (mouseX < stage.stageWidth/2 && mouseX > 0) {//left of stage explicitly
			speed = -(mouseX - stage.stageWidth/2) / 8;
		}
		else if (mouseX > stage.stageWidth/2 && mouseX < stage.stageWidth) {//right of stage explicitly
			speed = -(mouseX - stage.stageWidth/2) / 8;
		}
		scroller.x += speed;

		//scroller limits
		if (scroller.x < -scroller.width + stage.stageWidth - 20) { //if scrolled too far left
			scroller.x = -scroller.width + stage.stageWidth - 20;
		}
		else if (scroller.x > 20) { //if scrolled to far right
			scroller.x = 20;
		}
	}
}

Step 17: User Friendly Movement

Now test this and think about your end user. You’ll be looking at this image scroller and maybe wanting to look a bit closer or focus in on an image that catches your eye. You want this scroller to stop moving, (if I move to the center of the stage it still drifts to one side of the other) and I focus more on fighting the scroller than I do on the image I want to look at.

This is an example of a non-transparent user control. We want the user to be able to intuitively use this scroller to the point that they don’t even think about it. If the user has to think about it, or even worse, fight your app to get it to do something, you lose and they will look elsewhere for their content. So let’s avoid the struggle and give the scroller a dead area at the center of the stage. Then they can rest at ease by moving to the center of the scroller to inspect something or stop the motion sickness. It’s a really easy thing to do and has a big payoff, making the scroller easier to use. Rather than using the center of the stage for all our calculations we’ll give it some padding.

function moveScrollerThumbs(e:Event):void {
	if ( mouseY > scroller.y && mouseY < scroller.y + scroller.height) {//vertically over scroller
		if (mouseX < stage.stageWidth/2 - 40 && mouseX > 0) {//left of stage explicitly
			speed = -(mouseX - (stage.stageWidth/2 - 40)) / 8;
		}
		else if (mouseX > stage.stageWidth/2 + 40 && mouseX < stage.stageWidth) {//right of stage explicitly
			speed = -(mouseX - (stage.stageWidth/2 + 40)) / 8;
		}
		else {
			speed = 0; //if in the center area, clear the speed to 0 so we don't have any roll over effect from the last frame.
		}
		scroller.x += speed;

		//scroller limits
		if (scroller.x < -scroller.width + stage.stageWidth - 20) { //if scrolled too far left
			scroller.x = -scroller.width + stage.stageWidth - 20;
		}
		else if (scroller.x > 20) { //if scrolled to far right
			scroller.x = 20;
		}
	}
}

Step 18: Abstracting Movement More

Let’s abstract this out a bit. We have multiple places where we are adding padding to values or measurements. It’d be best practice to create a variable to hold our padding value and apply the same value easily by applying the variable every time we want padding. This would help us update if a client later says “I like it, but can we spread it out some?” or the dreaded… “Something’s off about this…”, then we’d just update the variable and it would be ready to go. I always try to create controls for myself, the programmer, to make it easy to customize a project.

I’ve created a variable named “padding” here and am applying it everywhere that makes sense. Notice that in a couple places I multiply it by 2, use your own judgment here – if you want more padding give it more, of course we could take it further and have a “padding_small” variable and another “padding_large” variable, but one will do justice for the purpose of this tutorial. You get the idea. This doesn’t really change the end file, but it can help to make your life much easier and your code simpler, more understandable or readable.

import caurina.transitions.*;

//load xml
var xmlLoader:URLLoader = new URLLoader();
var xmlData:XML = new XML();
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);

var xmlPath:String = "image-scroller.xml";
xmlLoader.load(new URLRequest(xmlPath));
trace("loading xml from: " + xmlPath);

function LoadXML(e:Event):void {
	trace("xml loading complete");
	xmlData = new XML(e.target.data);
	//trace(xmlData.image);
	buildScroller(xmlData.image);
}

var scroller:MovieClip = new MovieClip();
var speed:Number;
var padding:Number = 20;

this.addChild(scroller);
scroller.y = scroller.x = padding;
//build scroller from xml
function buildScroller(imageList:XMLList):void{
	trace("build Scroller");
	for (var item:uint = 0; item < imageList.length(); item++ )  {
		var thisOne:MovieClip = new MovieClip();

		//outline
		var blackBox:Sprite = new Sprite();
		blackBox.graphics.beginFill(0xFFFFFF);
		blackBox.graphics.drawRect( -1, -1, 142, 107);
		thisOne.addChild(blackBox);

		thisOne.x = (140 + padding) * item;
		thisOne.itemNum = item;
		thisOne.title = imageList[item].attribute("title");
		thisOne.link = imageList[item].attribute("url");
		thisOne.src = imageList[item].attribute("src");

		//image container
		var thisThumb:Sprite = new Sprite();
		//add image
		var ldr:Loader = new Loader();
		var urlReq:URLRequest = new URLRequest(thisOne.src);
		trace("loading thumbnail "+item+" into Scroller: " + thisOne.src);
		ldr.load(urlReq);
		//assign event listeners for Loader
		ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
		ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
		thisThumb.addChild(ldr);
		thisOne.addChild(thisThumb);

		//create listeners for this thumb
		thisOne.buttonMode = true;
		thisOne.addEventListener(MouseEvent.MOUSE_OVER, overScrollerItem);
		thisOne.addEventListener(MouseEvent.MOUSE_OUT, outScrollerItem);
		thisOne.addEventListener(MouseEvent.CLICK, clickScrollerItem);

		//add item
		scroller.addChild(thisOne);
	}

	scroller.addEventListener(Event.ENTER_FRAME, moveScrollerThumbs);
	trace("termination of build scroller");
}

function overScrollerItem(e:MouseEvent):void {
	trace("over" + e.currentTarget.name);
}
function outScrollerItem(e:MouseEvent):void {
	trace("out" + e.currentTarget.name);
}
function clickScrollerItem(e:MouseEvent):void {
	trace("clicked item " + e.currentTarget.itemNum + " - visit url: " + e.currentTarget.link);
}
function completeHandler(e:Event):void {
	//trace("thumbnail complete "+e.target.loader.parent.parent.name);
	//size image into scroller
	resizeMe(e.target.loader.parent, 140, 105, true, true, false);
	Tweener.addTween(e.target.loader.parent.parent, { alpha:1, time: .5 } );
}
function errorHandler(e:IOErrorEvent):void {
	trace("thumbnail error="+e);
}

//The resizing function
// parameters
// required: mc = the movieClip to resize
// required: maxW = either the size of the box to resize to, or just the maximum desired width
// optional: maxH = if desired resize area is not a square, the maximum desired height. default is to match to maxW (so if you want to resize to 200x200, just send 200 once)
// optional: constrainProportions = boolean to determine if you want to constrain proportions or skew image. default true.
function resizeMe(mc:DisplayObject, maxW:Number, maxH:Number=0, constrainProportions:Boolean=true, centerHor:Boolean=true, centerVert:Boolean=true):void{
    maxH = maxH == 0 ? maxW : maxH;
    mc.width = maxW;
    mc.height = maxH;
    if (constrainProportions) {
        mc.scaleX < mc.scaleY ? mc.scaleY = mc.scaleX : mc.scaleX = mc.scaleY;
    }
	if (centerHor) {
		mc.x = (maxW - mc.width) / 2;
	}
	if (centerVert){
		mc.y = (maxH - mc.height) / 2;
	}
}

function moveScrollerThumbs(e:Event):void {
	if ( mouseY > scroller.y && mouseY < scroller.y + scroller.height) {//vertically over scroller
		if (mouseX < stage.stageWidth/2 - padding*2 && mouseX > 0) {//left of stage explicitly
			speed = -(mouseX - (stage.stageWidth/2 - padding*2)) / 8;
		}
		else if (mouseX > stage.stageWidth/2 + padding*2 && mouseX < stage.stageWidth) {//right of stage explicitly
			speed = -(mouseX - (stage.stageWidth/2 + padding*2)) / 8;
		}
		else {
			speed = 0;
		}
		scroller.x += speed;

		//scroller limits
		if (scroller.x < -scroller.width + stage.stageWidth - padding) { //if scrolled too far left
			scroller.x = -scroller.width + stage.stageWidth - padding;
		}
		else if (scroller.x > padding) { //if scrolled to far right
			scroller.x = padding;
		}
	}
}

Step 19: Adding Scale Tweens

With this idea of using variables to customize our file, let’s add some bling with the Tweener library we already added. It’s great to call out the item in the scroller the user rolls over, so let’s have it scale a bit larger to help it stand out. This is where the beauty of Tweening comes in. Just one line of code, some variables and we can tell it to tween the scaleX and scaleY of the scroll item. If we’re scaling the item we’ll want to also translate its coordinates a bit so the item is still centered, this looks like tricky math, but it’s actually pretty simple.

First, we add a variable to each object to store it’s starting x position, we can just call it myx and put it on the same line where we calculate the x (we do this so we can reliably move the item back to it’s rightful place when we need to). We need to move it so the item is still centered, so we find its current width and factor it by half the scale we are applying. We do this for x and y. Then we need to tween it back to its starting size and coordinates on the mouse out event handler.

thisOne.x = thisOne.myx = (140 + padding) * item;
...
var thumbSmall:Number = 1;
var thumbLarge:Number = 1.1;
function overScrollerItem(e:MouseEvent):void {
	//trace("over" + e.currentTarget.name);
	Tweener.addTween(e.currentTarget, { scaleX:thumbLarge, scaleY:thumbLarge, x:e.currentTarget.myx - e.currentTarget.width * Math.abs(thumbSmall - thumbLarge)/2, y: -e.currentTarget.width * Math.abs(thumbSmall - thumbLarge)/2, time:1 } );
}
function outScrollerItem(e:MouseEvent):void {
	//trace("out" + e.currentTarget.name);
	Tweener.addTween(e.currentTarget, { scaleX:thumbSmall, scaleY:thumbSmall, x:e.currentTarget.myx, y:0, time:1 } );
}

Step 20: Adding Border Tweens

Let’s make them stand out even more by fading the white ‘blackBox’ around the thumbnails (just realizing that I named the white box black =) ). This one is easier than the previous step. Just add a couple of variables for the fade in and out values (alpha) and add the Tweens to both the over and out event listener handler function. We’ll also need to ensure that we can address the blackBox sprite so when we initialize it let’s explicitly name it. While we’re at it we can set the initial alpha of the box to equal the thumbFadeOut variable.

//outline
var thumbFadeOut:Number = .2;
var thumbFadeIn:Number = 1;
var thumbSmall:Number = 1;
var thumbLarge:Number = 1.1;
...
var blackBox:Sprite = new Sprite();
blackBox.graphics.beginFill(0xFFFFFF);
blackBox.graphics.drawRect( -1, -1, 142, 107);
blackBox.alpha = thumbFadeOut;
thisOne.addChild(blackBox);
thisOne.blackBox = blackBox;
...
function overScrollerItem(e:MouseEvent):void {
	//trace("over" + e.currentTarget.name);
	Tweener.addTween(e.currentTarget, { scaleX:thumbLarge, scaleY:thumbLarge, x:e.currentTarget.myx - e.currentTarget.width * Math.abs(thumbSmall - thumbLarge)/2, y: -e.currentTarget.width * Math.abs(thumbSmall - thumbLarge)/2, time:1 } );
	Tweener.addTween(e.currentTarget.blackBox, { alpha:thumbFadeIn, time: 1 } );
}
function outScrollerItem(e:MouseEvent):void {
	//trace("out" + e.currentTarget.name);
	Tweener.addTween(e.currentTarget, { scaleX:thumbSmall, scaleY:thumbSmall, x:e.currentTarget.myx, y:0, time:1 } );
	Tweener.addTween(e.currentTarget.blackBox, { alpha:thumbFadeOut, time: 1 } );
}

Step 21: Adding Link on Click

Speaking of all the event listeners, we still haven’t finished coding the click event. We want to have the click basically be a link click and link the user to the url specified in the xml. For this, we just pass the link value from the event’s target that we are currently tracing, to a URLRequest object and try to navigate to it with our friend navigateToURL. There we have it.

function clickScrollerItem(e:MouseEvent):void {
	//trace("clicked item " + e.currentTarget.itemNum + " - visit url: " + e.currentTarget.link);
	var urlRequest:URLRequest = new URLRequest(e.currentTarget.link);
	try {
		navigateToURL(urlRequest);
	}
	catch (e:Error) {
		// handle error here
		trace(e);
	}
}

Conclusion

I hope you enjoyed this tutorial and that you learned something. You should now have a pretty good grasp on AS3 and xml, loading and resizing images, easy animating with tweening, mouse event listeners, scrolling and user friendly interactive design!

Was it easy to follow? I usually do tutorials in open source examples so I don’t know if I droned on too much here.. Feel free to let me know in the comments. This tutorial is meant to be a spring board for ideas; there are tons of other things we could to with this file and get many other effects going, but this should get you started!

Evan Mullins is circlecube on Activeden
Add Comment

Discussion 94 Comments

Comment Page 1 of 21 2
  1. Fred says:

    Very nice tutorial.
    My only criticism would be that it would have been nicer if it were a class.

  2. MSFX says:

    some smoothing on the images would make the scaling look SO much nicer..

  3. André says:

    Wow
    nice but too many codes!!

    Thanks anyway!! :D

  4. Chris says:

    looks good, will try it later

  5. Nice, maybe a little fast but excellent.

  6. Franky says:

    Great into to XML parsing

  7. jamie says:

    Very nice, I have tried this with only 3 images however and the thumbnails jump around all over the place. Maybe I should try to change the dimensions of the box?

    • jamie says:

      also the scroller gets added to the stage with this.addChild(scroller); right?
      I have a movie clip I’v added to the stage balled box_mc. How would I add the scroller so that is goes inside that movie clip and not the stage?

      • Evan Mullins says:
        Author

        @Jamie –

        Yea, the dimensions of your box/stage should be larger than the scroller, so updating the dimensions will help with only having 3 images. If the scroller.width is less than the stage width, I can see that freaking out the interactive code… ;)

        To add the scroller to box_mc rather than the stage you’d code: box_mc.addChild(scroller);

      • teo says:

        if you don’t want to change the dimensio of yor box/stage and have only 3 images you could add:

        if (scroller.width < stage.stageWidth) {
        scroller.x = padding;
        }

        inside the function moveScrollerThumbs
        this'd prevent the code to freak out … ;)

  8. Alex says:

    Good tutorial, very thorough and teaches a lot of different basic skills for working in flash. I actually had just learned XML parsing and adding images the other night so this was just in time. For anyone looking to add smoothing to the images just add these two lines in the ‘completeHandler’ function:

    var image:Bitmap = Bitmap(e.target.content);
    image.smoothing = true;

    That should smooth out the images when they resize.

  9. alexandru asmarandei says:

    hello,
    very nice tut, very well explained. i do have one question. let’s say i already have created a ‘scroller’ which has a nice look, and i’ve already placed some containers for thumbnails in the scroller. what would be the simpliest code to load pictures from xml into those specific containers? (everything else, including movement is done separately)
    i will start with this:
    var xmlLoader:URLLoader = new URLLoader();
    var xmlData:XML = new XML();
    var xmlPath:String = “pictures_xml.xml”;
    xmlLoader.load(new URLRequest(xmlPath));
    this part is enough for loading the xml, correct? (let’s say that the pictures are small enough so i will not need the complete event listener.)
    what i need now is to put the infos from xml into my scroller and make so that when i press one image i got the big one loaded into a different container. and here i got stucked.
    can you, please, help me? you can name however you want the containers and the scroller.
    thanks you very much,
    alex

    • Evan Mullins says:
      Author

      @alexandru –

      Your wanting to load the larger image into a container in flash rather than opening up the link in the browser? You shouldn’t have to do much at all with the xml parsing, just update the click event listener (found in step 21) to load the image internally rather than navigateToURL. Good luck!

      • Some of the tutorials have good functionality lesson’s. Even though the functionality is there. Standard designed features should be shown. Not left in the air.

        There are basic thing’s a designer for instance would like, I wish you extended this lesson to include the click event listener to load internally, thanks.

        You did a great job.

  10. I love the Milestone Execution of this tutorial. Great Work!

  11. taha says:

    wow , amazing tutorial !!

    thanks, it was very informative and useful for me !

    ur blog, goes to my bookmarks, i will just start exploring it !

  12. Clay Jackson says:

    Thanks! Will use this.

  13. Prabhu says:

    Great nice work!!! it is amazing work you have done. I have a small query on this; is that we can have an auto Scroll on this?

  14. Jerome Frederick says:

    Awesome tutorial! Say I wanted to make the Url open up on the current page instead of a new one. What would i have to edit. Thanks in advance

  15. cain says:

    yes it’s good thanks for the tutorial, If I may have a request it would be more sensible if the previe of the big picture is in the same page like in the buttom or at the middle or so

  16. Fabian says:

    Great Tuturial!!!

    But i got A problem: if i change: var thumbLarge:Number = 1.1; to a valua a lot bigger (for example 1.6) the scale will work, but i cant see the full image because the ones which have been loaded later will hide it.

    i know i have to add the current image again so that it will be on top of the display list, but i don´t know how to manage this

    maybe you can help me with this problem

    thanks a lot

  17. Michael Tully says:

    Fantastic TUT mate,

    Would be better a cleaner put in to a class, one question i have would be how to get this to take the full width of any screen and still scroll correctly.

    Could anyone shed abit of light on to this

  18. Hussein says:

    brilliant mate – learned a lot from this, everything is well explained thanks a lot for sharing

  19. Ajit says:

    That seems to be a nice tutorials and i also want to do some stuff like this i m new to flash action script so plz suggest me some better way of getting started with flash action script i am waiting for your reply, you can mail me at ajitajoit@gmail.com.

  20. Jared says:

    Thanks! Awesome tutorial.

    It really helped with a lot of technical things I was struggling with. (especially since it turns out Im working on a project that requires a thumbnail scroller, hence landing on this page, obviously! ;) ) One question though… the thumbnails dont show any loading progress. What would you recommend as the simplest way to add a load-progress feature to each of the thumbnails?

    A little progress loader per thumbnail would really finish off this tutorial perfectly for me!

    If you have time, I would love a little advice and help with that! Much appreciated. You can send it to my email. Thanks

  21. Abhilash Oleti says:

    very nice tutorial, but along with this i want image title also has to appear below the image, can u help me out….

  22. jdinh says:

    Great tutorial!
    I was wondering if you can tell me how to display the “title” under each thumbnail. It’ll be great if you can help me out THANKS!

    Your Awsome!

  23. Pablo Brandon says:

    Hi thaks for the great tutorial! It reaaly helped me out!

    The scroller works great by itsef.

    But I’m having problems when import the scoller as an external SWF to a main site. When i test the site, the scroller dosen’t scroll its whole extension to show all the thumbs in line. Is the scroller mixing it’s stage (mouse control) setting with the main site’s stage size (1600X1200)?
    I dont know very much about coding, how coud is fix this?

    Your Awsome!

  24. Justinho says:

    Really great tutorial Evan!! I found it really useful!

    I haven’t followed it word for word as its not quite right for an image library I’m trying (understandably).

    I’ve done the loading slightly differently, I split the code into to a thumbnail and a document class, I’ve also used a different tween engines plus some other bits.

    I’ll look out for any other tutorials u have!

  25. Sjef says:

    Thanks for this great tutorial! Only there is one thing I don’t understand(maybe it’s because I’m new and not (yet) familiar with AS3 and Flash).

    I want to place this scroller in a Movieclip with specified boundaries. I already read the option a few comments earlier to add the scroller to box_mc.addChild(scroller) instead of this.addChild(scroller). If I do so then the scroller doesn’t scroll and the right side doesn’t stop showing at the end of the Movieclip boundary, but at the end of the stage. So I was wundering if there is a way to put this scroller in a box and doesn’t scroll page width but box width?

    Thanks for your help!

    • Sjef says:

      Well, i’m a bit further. I discovered the place in the code to specify the area where the mouse have effect. I also discovered the place where I can specify the limits of the scrollbar (max left, max right). They are all set in the right position.
      Now, I only need to let the scroller show in the box_mc and not on the whole stage width. Anyone who can help me? Thanks!

      • Johan says:

        You can use a masked layer to make the banner move within a restricted area. First create a new layer and draw onto this layer a rectangle with a fill (the color does not matter). This rectangle determines which part of the banner will be visible, so you can keep some space from the borders of the stage. Modify the rectangle into a movie clip, e.g. mc_Mask. Give the movie clip an instance name, e.g. myMask. Move the Actions-layer beneath the Mask-layer. Then rightclick the layer en select the option ‘Mask’. You’ll see that the Actions-layer has become a part of the Mask.
        In the actionscript code, after declaration of the movieClip ‘scroller’, add this line to your code :
        scroller.mask = myMask;

        Now the banner scrolls only into the visible part of the mask, which is the rectangle movieClip that has been added to the stage.

    • Brad says:

      Awesome tutorial! Very good job!

      One question – I have set my stage width in the html to 100% (I want to center this and make it scroll right even when my browser is resized)

      How can I do this?

  26. Anas manaa says:

    Wonderfull tutorial

    thank you very much

  27. bruno says:

    Excellent !
    But to fast for me in the resizeMe function (conditions details (the first one)) I would appriciate more details.
    Result looks better with a LineStyle property applied at the “BlackBox”.
    Anyway Thanks ……..

  28. suzi says:

    Is there a way to load this into another fla file? I followed this tutorial and created the scroller, but now I want to add it to another flash project I have. I tried importing the f4v but it just shows the static background. I’m not even sure if that’s the right way to go about it but it’s the only thing I could think of. If anybody could let me know about this it would be a big help, thanks.

  29. Sreelash says:

    THank you very. Understanding tutorial. Actually i was confused with using multiple movieclips using actionscript3. I understood.Thanks a lot.

  30. jack says:

    thx thx thx Evan Mullins
    this tutorial is really nice.
    hit it up ^.^ hope to see u tutorial again

  31. antonis says:

    hi there!

    this is a great tutorial!

    However, how is it possible to set the Scrolling start automatically from right to left so it looks like a slideshow? i have been searching the whole net for this and still cant find any useful tutorial

    regards

  32. Mike says:

    Thanks for the turtorial. I just have one question:

    Is it possible to make the clip loop to autoscroll when the mouse isn’t on the moive?

    Any hel would be much appreciated. Thanks in advance.

    Mike

  33. misho says:

    Well done!
    ¨
    How do i have the big thumb on top level in the stack? I know i have to addChild again how to do this?

  34. richard says:

    Great tutorial,
    i’m having a problem when i click to a new frame and it seems like a loop is still running causing the rest of my script to run slower, is there anyway to prevent this?

  35. imit says:

    the cat looks like my friend’s cat
    http://zeytin.uluask.com

  36. Karen says:

    I just don’t get this tutorial. Any part of it. I’m very new to Flash and understand that you need to know code. I never get a result and always get stuck on the second or third steps – what am I doing wrong?

  37. Really really great tutorial, , one question though (like Jared who’s commented further up) I too would love to be able to preload the thumbnails. Is this possible or is it quite a big task?

  38. FSoria says:

    Great Tutorial
    Complete, I’ve learned a lot. And some tricks that liked me. Thnx

  39. Jennifer says:

    Nice!
    I would love to see something like this that uses dynamic text (or at least text written into the AS3 script) that does something similar to what you have here. This is not an easy example to find for an AS3 n00b like myself.
    Thanks for posting this example with your explanation. I’ve used one of your other examples and find them easy to follow.

  40. Paul says:

    Great tutorial!

    It works good for me, but I would like to add the title extract from the xml file beside my images.

    My scroll is vertical so it will make something like:

    Img 1 title
    Img 2 title
    Img3 title

  41. duy says:

    how do i make this start automatically and keep on looping? please let me know. thank you.

  42. Emil says:

    The tutorial is great!
    I have one question? I want to link the thumbs to labeled frames in timeline, not to external files. Can you tell me how i must change the function clickScrollerItem to go to the frames?

  43. MATTANIAH says:

    i am totally lost at step 4. I am a beginner to actionScripting. what steps were left out of the tutorial? Please help me understand what i’m not doing! thanks!

    i really like your end result and am squandering countless hours of my life trying to figure this out.

  44. Guily says:

    Thank you for this

    But, it would be a perfect tutorial if… If we could link the thumbs to a ui loader container, not to external files. Can you tell me how i must change the function clickScrollerItem to go to the container?

    Your saying update the click event listener (found in step 21) to load the image internally rather than navigateToURL. Can you be more explicit, please.

  45. Taylor says:

    Slick tutorial.
    Can anyone help me make a vertical scroller? New to action script as well. I’m doing a project for my dad who’s trying to post a website for his art portfolio for work.

  46. Moh says:

    Great tutorial!

    would that be possible if I use this scripts to do the scrolling effect which not have the xml supported image but a single movie clip like “scroller” in which a big image has been inserted.

    What I made is a big image bigger than my stage size. Whenever I go to the edge it will scroll the image as same as it is. I belive I made it pretty clear…. any solution….would be very helpfull…i am new and i need this very awefully…

    THANKS IN ADVANCED!

  47. Camello says:

    How to increment, preloaders into objects?

  48. kishan patel says:

    Really very nice tutorial,
    It gives a fundamental things which are newbee to as3..

  49. justin says:

    How can I make this a vertical slider?

Comment Page 1 of 21 2

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.