Flex 4 ActionScript 3 Lightbox for Flash Player

by David Salahi on June 27, 2010

Here’s a class that duplicates the popular JavaScript lightbox effect entirely in ActionScript 3 for Flex 4 projects. Here’s a demo of the Lightbox class in action. Right-click to view source or download the fxp at the end of this post. (Note: it takes a few seconds after loading this page for all the images to be loaded.):

As usual, when you click on any image the lightbox pops up with that image and dims down the background. Previous/next buttons are included and when switching from one image to the next the lightbox animates the resizing process. Use is made of the Flex Scale, Fade and Move effects. These effects are combined in both Parallel and Sequence effects to either play multiple effects simultaneously or one after the other.

The Lightbox class is easy to use, requiring only two inputs:

  • a Vector of LargeImage objects
  • the stage size

The stage size is passed into the constructor and the lightbox is added to the display list:

  // Create a lightbox
  _lightbox = new  Lightbox(610, 600);       // matches app  stage size
  addElement(_lightbox);
  _lightbox.visible =  false;

The large images are loaded at run-time using a Loader. When all of the large images have been loaded the Vector of LargeImage value objects is created and passed to the lightbox:

  var images:Vector.<LargeImage> = new  Vector.<LargeImage>;
  for(var i:int = 0; i < _bitmaps.length; i++)
  {
    var  largeImage:LargeImage = new LargeImage("Image " + i, i, _bitmaps[i]);
    images.push(largeImage);
  }
  _lightbox.images = images;         //  Provide the set of large images to the Lightbox class

Each LargeImage object contains three pieces of information: the image’s Bitmap, its title and an ID. The title or description is displayed in the caption area below the image. The ID is used to identify which image to display when the user clicks on one a thumbnail.

At this point, the lightbox is ready for action. To display the lightbox just call its showImage method with the ID of the image to display.

The Lightbox Class

The Lightbox class is composed of the following main parts:

  • a dark, translucent dimmer which overlays the stage and dims down everything except the current large image
  • a lightboxBackground which is just a white rectangle which provides the frame for the image
  • a bitmapContainer which allows the Bitmap to be added to the display list and positioned on the stage
  • a white captionArea background for the caption
  • a Label caption which displays whatever text is provided for the title

In the constructor these various parts are drawn, as needed, and added to the Lightbox (which extends UIComponent).

When showImage is called the following sequence of events is started:

  1. Find the requested image ID (in showImage) and calculate the size of the background/frame which includes a bit of padding. showImage then calls resizeLightbox.
  2. resizeLightbox calculates the x & y scale factors needed to resize the lightboxBackground to fit the current image. It then creates two Flex Scale effect objects and combines them in a Sequence effect so that first the width is adjusted and then the height.
  3. When the Sequence effect has ended fadeInImage is called. The bitmapContainer is positioned on top of the lightboxBackground and the image is added to it. The close, previous and next buttons are also positioned. Then, all three buttons are faded in together with the image.
  4. When the Fade in effect has ended showCaptionArea is called. The captionArea width is adjusted to match the width of lightboxBackground. A fade in (Fade) and a slide down (Move) are combined in a Parallel effect so that both play simultaneously.
  5. Once the caption area is in place showCaption is called to set the title for the current image and to fade in the Label.

That’s about it. Clicking the previous/next buttons just repeats the steps above and clicking the close button fades everything out. Enjoy!

Download the Flex 4 ActionScript 3 lightbox sample project.

{ 19 comments… read them below or add one }

hellix July 25, 2010 at 6:20 pm

Hi.
I’m using your component and everything works fine. :) Thanks!

skiper August 4, 2010 at 10:28 am

Hi,
thanks for this component. It’s cool :-)
However there is a small bug in the Lighbox.as. If you click on next/last image button the label of previous image will not disappear until the next label is not rendered. Set backgound color e.g. to white color to see this.
To fix this add

if(this.contains(_caption)) removeChild(_caption);

to showImage method.

David Salahi August 5, 2010 at 9:16 pm

Yes, skiper, you’re exactly right. I missed that because of the black background. But your fix takes care of it so I’ve added that line of code to the project and updated the samples.
Thanks for the fix!
Dave

Evgeni October 28, 2010 at 4:51 am

Hi,

I spent quite some time looking for Lightbox component for my Flex application. Finally found it!

Thanks a bunch,
Evgeni

Amishi Shah November 1, 2010 at 5:53 am

I am trying to use it. But I get the below error everytime.

Error #2044: Unhandled IOErrorEvent:. text=Error #2036: Load Never Completed.

Can anyone help on the same. I have tried using try-catch also. But in none of the methods the execution comes to a catch block.

Please help me solve the issue if anyone has any idea.

Regards,
Amishi

David Salahi November 1, 2010 at 2:12 pm

@Amishi
Have you tried Googling the error? There were lots of hits when I tried just now. This one shows how to add an error event handler:
http://stackoverflow.com/questions/1227839/how-to-resolve-adobe-flex-error-error-2036-load-never-completed

The first thing to do is to get more info about what’s failing. My guess is that your images aren’t loading. The usual suspects in that case is a file that is not at the specified path.

Hope this helps,
Dave

lorenzo radice March 14, 2011 at 2:47 am

Hi, that’s a great work, I’m using it :) I found a bug, did u know it?
When u click on the lighbox close button before the label has been set visible, that label will remain visible forever (in your example it’s a grey background on dark label text, so use eagle eyes to find the label, but if you use a different background, eg. white, u will find “permanent” labels quicky).

So follow these steps to get the bug:
- click on a image
- after u see the fullsize image, but BEFORE the bottom label appears, click the close button

Thus, is it possibile to set visible the close button only after image and label have completely been shown?

Lorenzo

lorenzo radice March 14, 2011 at 3:02 am

yep, just to knwo how I resolved the bug.

In showCaption() I added an array of objects:
var fadeIn:Fade = new Fade(_caption);
fadeIn.alphaTo = 1;
fadeIn.play([_caption, _closeBtn]);

In fadeInImage() I deleted the _closeBtn:
var fadeIn:Fade = new Fade();
fadeIn.alphaTo = 1;
fadeIn.addEventListener(EffectEvent.EFFECT_END, showCaptionArea);
fadeIn.play([_bitmapContainer/*, _closeBtn*/]);

This seems to resolve the permanent label display bug.
Lorenzo

Jason May 14, 2011 at 10:10 pm

I have been unable to get this to work. Do you have any idea why the lightbox would not show if I can prove that the showImage function is being called? It seems like it should run, but it doesn’t… Thanks

David Salahi May 15, 2011 at 8:55 am

@lorenzo
I was going to incorporate your bug fix into the source code and repost the project. However, when I tried to reproduce the bug I was unable to do so. To test, I downloaded a copy of the FXP and imported it into Flash Builder 4.5. Then, I changed the application background color to white. When I ran it I tried clicking the close button as soon as it became visible. Most of the time I was able to do that before the caption appeared. But regardless of whether the caption had appeared or not the entire large image disappeared. No caption was ever visible to me after closing the large image.

So, I’m wondering if you had made some change to the code which introduced the bug? I’m just not seeing it.

David Salahi May 15, 2011 at 9:07 am

@Jason
There could be lots of reasons but it’s impossible for me to guess without knowing more about your project. First, were you able to get the downloaded project working before making any changes? I just downloaded a copy from the FXP link above and it worked fine for me in Flash Builder 4.5 with the 4.5 SDK. (It was originally built with the V4 SDK and should also work fine with that.)

Of course, if you’ve made code changes there could be any number of reasons why it would fail. Since you say that showImage is being called try debugging through that function. First, see if it’s finding a match for the passed-in image id in the for loop. If so, check to make sure that _currentImage refers to a valid LargeImage. If the images didn’t get loaded properly then _images could be invalid so _largeImage could also be invalid.

If all that looks good try debugging into resizeLightbox. Check that the calculated end scale values are reasonable. In the original code they should be between approximately 3-5.

You can either set breakpoints and inspect things manually or else insert trace statements and watch the output.

Hope this helps,
David Salahi

Jason May 16, 2011 at 7:45 pm

It looks like it is due to me trying to use relative references instead of URL references. When I switched the code back to your hard coded URLs for the large images then it worked. Does this loader code work for relative references or do I need to host these images on the web?

Also, there is an issue that I can’t figure out. When I use the switch statement to match the source value with the relative thumbnail source value, it doesn’t work. I can take the value that I see in the debugger for the clicked source value and paste it into the switch and then it works! No idea what is going on there. I’ll place a code example below.

Works:
switch(“images\P1160018_thumb.jpg”){
case “images\P1160018_thumb.jpg”:
_lightbox.showImage(0); // pass the ID of the clicked image to the lightbox
break;

case “images\P3060001_thumb.jpg”:
_lightbox.showImage(1);
break;

case “images\P3060002_thumb.jpg”:
_lightbox.showImage(2);
break;
}

And this doesn’t work:
switch(image.source){
case “images\P1160018_thumb.jpg”:
_lightbox.showImage(0); // pass the ID of the clicked image to the lightbox
break;

case “images\P3060001_thumb.jpg”:
_lightbox.showImage(1);
break;

case “images\P3060002_thumb.jpg”:
_lightbox.showImage(2);
break;
}

And here is the image code that doesn’t match:

I have no idea what is going on. I am very puzzled. I have been testing by hardoding this images source into the criterion for the switch statement.

David Salahi May 16, 2011 at 8:16 pm

Jason,
I was able to use relative URLs like the following:
_largeImageFilenames.push(“images/64-large.jpg”);
_largeImageFilenames.push(“images/48-large.jpg”);
_largeImageFilenames.push(“images/92-large.jpg”);
_largeImageFilenames.push(“images/9a-large.jpg”);

I simply edited the four lines in the init() function of LightboxSample.mxml and it worked fine running on my local PC. That should also work fine from a server.

However, note that starting the URLs with a / would cause a problem; e.g.,
_largeImageFilenames.push(“/images/64-large.jpg”);

This caused an exception on my local PC.

Dave

Allie May 28, 2011 at 9:54 am

Sample ran fine – looking forward to integrating this into a project of mine. Thanks!

Jim August 6, 2011 at 12:02 pm

Can this be used for any spark components? like panel or datagrid. Basically a sophisticated popupmanager.

David Salahi August 7, 2011 at 1:14 pm

@guru_rags: you’re thinking of just a shell to contain a datagrid or a panel? To get the lightbox effect? It probably could. The Lightbox class extends UIComponent so you might want to modify it to extend a Container class instead.
David Salahi

Erdem September 10, 2011 at 2:41 am

Hi, I installed it, I like to picture a dynamic application with little modification. After the initial installation without restarting the program, but I can not upload a different picture. How do I delete pictures in the lightbox instead of shutting down the program to install the new pictures.

David Salahi September 10, 2011 at 8:24 am

Erdem,
I think you could just set a new Vector of LargeImages on the Lightbox (public function set images(value:Vector.<LargeImage>):void). You would, of course, have to load the images and build the Vector, as shown in the init and onComplete methods of LightboxSample.mxml, prior to setting the new Vector on the Lightbox class.
Dave

Erdem September 11, 2011 at 11:39 pm

Thanks David, I have found a way. again, I would delete the contents of the load variable, with the splice method _bitmaps

Leave a Comment

 

{ 1 trackback }

Previous post:

Next post: