ActionScript 3.0 Image Galleries
While Colin Moock’s Essential ActionScript 3.0 provides a great foundation for understanding how ActionScript works, I find myself straying from the book to find solutions to common problems, such as how to build an image gallery. As I mentioned before, I was looking at developing an interface similar to the Album View used by Viewzi. Here’s what I’ve come up with so far:
The Box Class
First, I started by creating a Box class that I could use to build frames for the images. It’s pretty basic, providing parameters for width, height and color.
package {
import flash.display.Shape;
public class Box extends Shape {
public function Box (w:Number,
h:Number,
fillColor:uint):void {
graphics.beginFill(fillColor, 1);
graphics.drawRect(0, 0, w, h);
}
}
}
The ImageFrame Class
Next, I created a class that creates an image frame with two instances of the Box class, one for the image placeholder, with parameters for width, height, color and margin, and one for the image frame, with parameters for color and padding.
package {
import flash.display.*;
public class ImageFrame extends Sprite {
public function ImageFrame (imageWidth:uint, imageHeight:uint, imageColor:uint, frameColor:uint, padding:uint):void {
var imageFrame:Sprite = new Sprite();
// Create image placeholder
var imageWidth:uint;
var imageHeight:uint;
var imageColor:uint;
var image:Box = new Box(imageWidth, imageHeight, imageColor);
// Create frame
var padding:uint;
var frameWidth:uint = imageWidth + (padding * 2);
var frameHeight:uint = imageHeight + (padding * 2);
var frameColor:uint = 0xFFFFFF;
var frame:Box = new Box(frameWidth, frameHeight, frameColor);
// Add frame and image to container
imageFrame.addChild(frame);
imageFrame.addChild(image);
// Center image in frame
image.x = padding;
image.y = padding;
// Add imageFrame
addChild(imageFrame);
}
}
}
Floating Grid
These two classes then provided the basic building blocks to experiment with gallery configurations. The first attempt produced a grid of images that could be centered on the stage with a Tween effect added. To access the fl.transitions library, I copied the directory from the Flash CS3 ActionScript 3.0 classes built into the application. I found them here:
/Applications/Adobe Flash CS3/Configuration/ActionScript 3.0/Classes/fl/
I copied the classes into my development directory:
~/flex/data/interface/fl/
That way, I could access these classes using the Flex 3 SDK by importing the classes:
import fl.transitions.*;
import fl.transitions.easing.*;
To compile SWF files, I use this command in Terminal:
flex/bin/mxmlc flex/data/interface/FloatingGrid.as
I ran into some interesting problems created by attempting to add transitions to a scale effect on the mouse over state of each of the image frames. The Tween class appears to override the variables set to position the image frames in the container sprite. I may be able to solve the problem by setting a different registration point, something which doesn’t appear to exist in pure ActionScript 3.0 code, but can be created dynamically with a class such as the Dynamic MovieClip Registration class adapted by Oscar Trelles. At any rate, here’s what I came up with:
package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import fl.transitions.*;
import fl.transitions.easing.*;
public class FloatingGrid extends Sprite {
// Instantiate stage variables
public var sw:Number = stage.stageWidth;
public var sh:Number = stage.stageHeight;
public var bg:Shape = new Shape();
// Instantiate container variables
public var container:MovieClip = new MovieClip();
public var containerX:Number;
public var containerY:Number;
public var containerWidth:Number;
public var containerHeight:Number;
// Instantiate image parameters
public var imageNumber:uint = 36;
public var imageWidth:uint = 40;
public var imageHeight:uint = 40;
public var margin:uint = 25;
public var padding:uint = 4;
public var imageColor:uint = 0x999999;
public var frameColor:uint = 0xFFFFFF;
// Set size on mouse over
public var overScale:Number = 1.5;
public function FloatingGrid () {
// Turn scaling off and set alignment to top left
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
// Add a background color
bg.graphics.beginFill(0x666666, 1);
bg.graphics.drawRect(0,0,sw,sh);
addChild(bg);
// Add image frames to stage with the following parameters:
// (number, width, height, margin, padding)
imageFrames(imageNumber, imageWidth, imageHeight, imageColor, frameColor, margin, padding);
// Register event listener for stage resizing
stage.addEventListener(Event.RESIZE, resizeListener);
// Register event listener for mouse over effects
container.addEventListener(MouseEvent.MOUSE_OVER, over);
container.addEventListener(MouseEvent.MOUSE_OUT, out);
// apply tween
var myTween:Tween = new Tween(container, "x", Elastic.easeOut, 0, containerX, 3, true);
}
private function resizeListener (e:Event):void {
// Instantiate variables for current container position
var initContainerX:Number = container.x;
var initContainerY:Number = container.y;
// Determine stage width and height
sw = stage.stageWidth;
sh = stage.stageHeight;
// Set background to width and height of stage
bg.width = sw;
bg.height = sh;
// Center the container on the Stage
containerX = (sw / 2) - (containerWidth / 2);
containerY = (sh / 2) - (containerHeight / 2);
container.x = containerX;
container.y = containerY;
var containerTweenX:Tween = new Tween(container, "x", Elastic.easeOut, initContainerX, containerX, 3, true);
var containerTweenY:Tween = new Tween(container, "y", Elastic.easeOut, initContainerY, containerY, 3, true);
}
private function over (e:MouseEvent):void {
DisplayObject(e.target).scaleX = overScale;
DisplayObject(e.target).scaleY = overScale;
DisplayObject(e.target).x -= (imageWidth * (overScale - 1)) / 2;
DisplayObject(e.target).y -= (imageHeight * (overScale - 1)) / 2;
// var imageFreeTweenScaleX:Tween = new Tween(DisplayObject(e.target), "scaleX", Elastic.easeOut, 1, overScale, .5, true);
// var imageFreeTweenScaleY:Tween = new Tween(DisplayObject(e.target), "scaleY", Elastic.easeOut, 1, overScale, .5, true);
// var imageFreeTweenX:Tween = new Tween(DisplayObject(e.target), "x", Elastic.easeOut, 1, overScale, .5, true);
// var imageFreeTweenY:Tween = new Tween(DisplayObject(e.target), "y", Elastic.easeOut, 1, overScale, .5, true);
}
private function out (e:MouseEvent):void {
DisplayObject(e.target).scaleX = 1;
DisplayObject(e.target).scaleY = 1;
DisplayObject(e.target).x += (imageWidth * (overScale - 1)) / 2;
DisplayObject(e.target).y += (imageHeight * (overScale - 1)) / 2;
}
private function imageFrames (
imageNumber:uint,
imageWidth:uint,
imageHeight:uint,
imageColor:uint,
frameColor:uint,
margin:uint,
padding:uint):void {
// Instantiate image parameters
var imageCount:uint = imageNumber;
var imageX:int;
var imageY:int;
var imageOffset:Number = imageWidth + (padding * 2) + margin;
var imageFrames:Array = new Array();
// Calculate the columns and rows of images
var columns:uint = Math.floor(sw / imageOffset);
var rows:uint = Math.ceil(imageNumber / columns);
// Number of images per row
var imagesPerRow:uint = columns;
// Calculate the width and height of the container
containerWidth = columns * imageOffset - margin;
containerHeight = rows * imageOffset - margin;
// Create the container for the images
addChild(container);
// Center the container on the Stage
containerX = (sw / 2) - (containerWidth / 2);
containerY = (sh / 2) - (containerHeight / 2);
container.x = containerX;
container.y = containerY;
// Add image frames to the container
for (var row:int = 0; row < rows; row++) {
imageX = 0;
imageY = row * imageOffset;
// Determine number of images for last row
if (imageCount < imagesPerRow) {
imagesPerRow = imageCount;
}
for (var i:int = 0; i < imagesPerRow; i++) {
imageFrames[i] = new ImageFrame(imageWidth, imageHeight, imageColor, frameColor, padding);
// Add images for the current row
imageFrames[i].x = imageX + (i * imageOffset);
imageFrames[i].y = imageY;
container.addChild(imageFrames[i]);
// Decrement images left to display
imageCount--;
}
}
}
}
}
Gallery Slider
I never did find exactly what I was looking for in a gallery slider, although there are lots of examples out there. However, once I figured out that I shouldn’t be using a MouseEvent listener, but rather an Event.ENTER_FRAME listener and using the DisplayObject.mouseX variable, it all fell into place. By using some simple math, I could change the rate of acceleration based on how close the mouse position was to the left or right edges of the stage.
package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import fl.transitions.*;
import fl.transitions.easing.*;
public class GallerySlider extends Sprite {
// Instantiate stage variables
public var sw:Number = stage.stageWidth;
public var sh:Number = stage.stageHeight;
public var bg:Shape = new Shape();
// Instantiate container variables
public var container:MovieClip = new MovieClip();
public var containerX:Number;
public var containerY:Number;
public var containerWidth:Number;
public var containerHeight:Number;
// Instantiate image parameters
public var imageNumber:uint = 40;
public var imageWidth:uint = 100;
public var imageHeight:uint = 60;
public var margin:uint = 25;
public var padding:uint = 4;
public var imageColor:uint = 0x999999;
public var frameColor:uint = 0xFFFFFF;
// Set size on mouse over
public var overScale:Number = 1.25;
public function GallerySlider () {
// Turn scaling off and set alignment to top left
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
// Add a background color
bg.graphics.beginFill(0x666666, 1);
bg.graphics.drawRect(0,0,sw,sh);
addChild(bg);
// Add image frames to stage with the following parameters:
// (number, width, height, margin, padding)
imageFrames(imageNumber, imageWidth, imageHeight, imageColor, frameColor, margin, padding);
// Register event listener for stage resizing
stage.addEventListener(Event.RESIZE, resizeListener);
// Register event listener for mouse position
stage.addEventListener(Event.ENTER_FRAME, mousePositionListener);
// Register event listener for mouse over effects
container.addEventListener(MouseEvent.MOUSE_OVER, over);
container.addEventListener(MouseEvent.MOUSE_OUT, out);
// apply tween
var myTween:Tween = new Tween(container, "x", Elastic.easeOut, 0, containerX, 3, true);
}
private function resizeListener (e:Event):void {
// Instantiate variables for current container position
var initContainerX:Number = container.x;
var initContainerY:Number = container.y;
// Determine stage width and height
sw = stage.stageWidth;
sh = stage.stageHeight;
// Set background to width and height of stage
bg.width = sw;
bg.height = sh;
// Center the container on the Stage
containerX = (sw / 2) - (containerWidth / 2);
containerY = (sh / 2) - (containerHeight / 2);
container.x = containerX;
container.y = containerY;
var containerTweenX:Tween = new Tween(container, "x", Elastic.easeOut, initContainerX, containerX, 3, true);
}
private function mousePositionListener (e:Event):void {
var stageCenter:Number = sw / 2;
var quietZone:uint = 50;
var stageLeft:Number = stageCenter - quietZone;
var stageRight:Number = stageCenter + quietZone;
var maxOffsetX:Number = stageCenter - imageWidth;
// Move gallery left or right depending on mouse position
// Movement accelerates as mouse gets close to left or right edges of the stage
// A maximum offset value prevents the gallery from moving off the stage
if (stage.mouseX < stageLeft && container.x stageRight && (containerWidth + container.x > sw - maxOffsetX)) {
container.x -= (stage.mouseX - stageRight) / 10;
}
}
private function over (e:MouseEvent):void {
DisplayObject(e.target).scaleX = overScale;
DisplayObject(e.target).scaleY = overScale;
DisplayObject(e.target).x -= (imageWidth * (overScale - 1)) / 2;
DisplayObject(e.target).y -= (imageHeight * (overScale - 1)) / 2;
// var imageFreeTweenScaleX:Tween = new Tween(DisplayObject(e.target), "scaleX", Elastic.easeOut, 1, overScale, .5, true);
// var imageFreeTweenScaleY:Tween = new Tween(DisplayObject(e.target), "scaleY", Elastic.easeOut, 1, overScale, .5, true);
// var imageFreeTweenX:Tween = new Tween(DisplayObject(e.target), "x", Elastic.easeOut, 1, overScale, .5, true);
// var imageFreeTweenY:Tween = new Tween(DisplayObject(e.target), "y", Elastic.easeOut, 1, overScale, .5, true);
}
private function out (e:MouseEvent):void {
DisplayObject(e.target).scaleX = 1;
DisplayObject(e.target).scaleY = 1;
DisplayObject(e.target).x += (imageWidth * (overScale - 1)) / 2;
DisplayObject(e.target).y += (imageHeight * (overScale - 1)) / 2;
}
private function imageFrames (imageNumber:uint,
imageWidth:uint,
imageHeight:uint,
imageColor:uint,
frameColor:uint,
margin:uint,
padding:uint):void {
// Instantiate image parameters
var imageX:int;
var imageY:int;
var imageOffset:Number = imageWidth + (padding * 2) + margin;
var imageFrames:Array = new Array();
// Calculate the width and height of the container
containerWidth = imageNumber * imageOffset - margin;
containerHeight = imageHeight;
// Create the container for the images
addChild(container);
// Center the container on the Stage
containerX = (sw / 2) - (containerWidth / 2);
containerY = (sh / 2) - (containerHeight / 2);
container.x = containerX;
container.y = containerY;
// Add image frames to the container
for (var i:int = 0; i < imageNumber; i++) {
imageFrames[i] = new ImageFrame(imageWidth, imageHeight, imageColor, frameColor, padding);
// Add images for the current row
imageFrames[i].x = imageX + (i * imageOffset);
imageFrames[i].y = imageY;
container.addChild(imageFrames[i]);
}
}
}
}
Note: I updated the code by adding a maximum offset value to prevent the gallery from moving off the stage.
ActionScript 3.0 Galleries
There are some code examples available that I’ve been able to find so far:
- ActionScript 3 Full Browser XML Slideshow
- Simple ActionScript 3 Slideshow Engine
- ActionScript 3 Drag, Pan, Zoom XML Content
- Array based perpetual scrolling navigation AS3
Flash Galleries
About this entry
You’re currently reading “ActionScript 3.0 Image Galleries,” an entry on Bauhouse
- Published:
- July 12, 2008 / 10:00 pm
- Category:
- ActionScript
- Tags:
8 Comments
Jump to comment form | comment rss [?] | trackback uri [?]