Flash 8 Photo gallery AS

The photo gallery I produced in flash 8 is a simple experiment in flash AS 2 classes, inheritance and event modelling. The current gallery loads its information from an XML file, this XML file is currently rather large as it contains extraneous information intended for other presentation files.

The XML parsing is handled using the AS 2 XPath API Classes.

[as]import mx.xpath.XPathAPI;[/as]

This implementation uses only the flash 8 filters really but the plan is to actually hop, skip, and jump the future development straight into the AS3 frame work and class structure.

The code below is the AS classes that control the presentation as it currently stands, please excuse the lack of commenting these files are provided ‘As Is’.

the example presentation can be seen here

BmpImageLoad.as this is used as a basic Bitmap loader and button within the gallery. It is also the class that is used to display the ‘main’ larger image.

[as]import mx.controls.SimpleButton
import flash.filters.*;
import flash.geom.Matrix;
import flash.display.BitmapData;

class BmpImageLoad extends SimpleButton
{
private static var symbolName:String = “BmpImageLoad”;
private static var className:String = “BmpImageLoad”;
private static var bmpImageLoad:MovieClip;
private static var __int_intervalTime:Number=31;

private var boundingBox_mc:MovieClip;
private var __mc_contentHolder:MovieClip;
private var __mc_imageShell:MovieClip;
private var __mc_imageHolder:MovieClip;
private var __mc_imageDisplay:MovieClip;
private var __mc_imageLoadVal:MovieClip;

private var __int_bTotal:Number;
private var __int_lPercent:Number;
private var __loadInterval:Number;

private var __bln_isLoaded:Boolean = false;

private var __str_loadTarget:String

function dispatchEvent() {};
function addEventListener() {};
function removeEventListener() {};

public function BmpImageLoad()
{
mx.events.EventDispatcher.initialize(this);
}

private function init():Void
{
super.init();
boundingBox_mc._visible = false;
boundingBox_mc._width = width
boundingBox_mc._height = height;
}

private function size():Void
{
super.size();
boundingBox_mc._width = width
boundingBox_mc._height = height;
}

private function draw():Void
{
size();
createChildren();
}

private function removeChildren():Void
{
__mc_imageLoadVal.removeMovieClip();
__mc_imageDisplay.removeMovieClip();
__mc_imageHolder.removeMovieClip();
__mc_imageShell.removeMovieClip();
__mc_contentHolder.removeMovieClip();
this.filters = [];
}
private function createChildren():Void
{
removeChildren()
__mc_contentHolder = this.createEmptyMovieClip(“mc_contentHolder”, 0);
__mc_imageShell = __mc_contentHolder.createEmptyMovieClip(“mc_imageShell”, 0);
__mc_imageHolder = __mc_imageShell.createEmptyMovieClip(“mc_imageHolder”, 0);
__mc_imageDisplay = __mc_contentHolder.createEmptyMovieClip(“mc_imageDisplay”, 1);
__mc_imageLoadVal = drawSolidRect(__mc_contentHolder, width, height, 0xcccccc, null, null, “mc_mc_imageLoadVal”, 2);
__mc_imageLoadVal._yscale = 1;
__mc_imageLoadVal.cacheAsBitmap = true;
__mc_imageDisplay._visible = __mc_imageShell._visible = __mc_imageHolder._visible = false;

__mc_imageHolder._quality = “BEST”;

if(loadTarget != undefined && loadTarget.length)
{
removeInterval(this.__loadInterval, “__loadInterval”);
__mc_imageHolder.loadMovie(loadTarget);
setLoadInterval();
}
}

private function setLoadInterval():Void
{
this.__loadInterval = setInterval(this, “doContentLoad”, __int_intervalTime);
}
public function load()
{
isLoaded = false;
invalidate();
}

public function setSize(w:Number, h:Number)
{
super.setSize(w, h)
invalidate();
}

public function get isLoaded():Boolean
{
return __bln_isLoaded;
}
public function set isLoaded(val:Boolean)
{
__bln_isLoaded = val;
}

[Inspectable]
public function get loadTarget():String
{
return getTarget();
}
public function set loadTarget(val:String)
{
setTarget(val);
}

private function doContentLoad()
{
var comp = __mc_imageHolder;
var bLoaded = comp.getBytesLoaded();
var bTotal = comp.getBytesTotal();
var bln_hasSize:Boolean;
isLoaded = Boolean((bTotal == bLoaded) && (bTotal > 0));

bln_hasSize = isLoaded && comp._width >0 && comp._height > 0;

__int_lPercent = Math.floor((bLoaded/bTotal)*100);
__mc_imageLoadVal._yscale = __int_lPercent;

if(bln_hasSize)
{
removeInterval(this.__loadInterval, “__loadInterval”);
dispatchEvent({type:”bitmapImageLoaded”,target:this});
displayLoadedImage();
}
else
{
updateAfterEvent();
}
}

private function displayLoadedImage()
{
var int_glowColor:Number = 0x000000;
var flt_stageGlow:GlowFilter = new GlowFilter(int_glowColor, 0.45, 7, 7, 2, 3, false, false);
var flt_stageBevel:BevelFilter = new BevelFilter(1, 45, 0x999999, 1, 0x333333, 1, 0, 0, 255, 3, “inner”, false);
var __bmp_galleryThumb = new BitmapData(width, height, true, 0x00ffffff);
var mtx_imageMatrix:Matrix = new Matrix();

var int_xRatio:Number = (width/__mc_imageShell._width);
var int_yRatio:Number = (height/__mc_imageShell._height);
int_xRatio = int_yRatio = Math.min(int_yRatio, int_xRatio);

var int_imgWidthRatio:Number = (__mc_imageShell._width*int_xRatio);
var int_imgHeightRatio:Number = (__mc_imageShell._height*int_yRatio);
var tXpos:Number = (width -int_imgWidthRatio) /2;
var tYpos:Number = (height – int_imgHeightRatio) /2;

mtx_imageMatrix.scale(int_xRatio, int_yRatio);
mtx_imageMatrix.translate(tXpos, tYpos);

__mc_imageDisplay.attachBitmap(__bmp_galleryThumb, 0, “always”, true);
__bmp_galleryThumb.draw(__mc_imageHolder, mtx_imageMatrix, undefined, undefined, undefined, true);

__mc_imageDisplay._visible = true;
__mc_imageHolder.removeMovieClip();
__mc_imageLoadVal.removeMovieClip();

__mc_imageDisplay.filters =[flt_stageBevel];
this.filters = [flt_stageGlow];
}

private function removeInterval(int_Interval:Number, str_intervalName:String):Void
{
clearInterval(int_Interval);
this[str_intervalName] = undefined;
}

private function getTarget():String
{
return __str_loadTarget;
}
private function setTarget(val:String)
{
var int_imgExtL:Number = val.lastIndexOf(“.”) +1;
var int_imgPLenght:Number = val.length;

if((int_imgPLenght-int_imgExtL)<3) return -1;

var str_imgExt:String = val.substr(-(int_imgPLenght-int_imgExtL)).toLowerCase();
switch(str_imgExt)
{
case “jpg” :
case “png” :
case “gif” :
case “jpeg” :
isLoaded = false;
__str_loadTarget = val;
break;
default :
break;
}
load();
}

/* private drawing functions */
private function drawSolidRect(mc_target:MovieClip, int_w:Number, int_h:Number, int_fillC:Number, int_lineC:Number, int_lineW:Number, str_clipName:String, int_depth:Number):MovieClip
{
var mc_retClip:MovieClip = mc_target.createEmptyMovieClip(str_clipName, int_depth);
if(int_lineW != null && int_lineC != null) mc_retClip.lineStyle(int_lineW, int_lineC);
mc_retClip.beginFill(int_fillC);
_drwRct(mc_retClip, 0, 0, int_w, int_h);

mc_retClip.endFill();

return mc_retClip;
}
private function _drwRct(mc_clip:MovieClip, int_x1:Number, int_y1:Number, int_x2:Number, int_y2:Number):Void
{
mc_clip.moveTo (int_x1, int_y1);
mc_clip.lineTo (int_x2, int_y1);
mc_clip.lineTo (int_x2, int_y2);
mc_clip.lineTo (int_x1, int_y2);
mc_clip.lineTo (int_x1, int_y1);
};
}[/as]

BmpImageList.as uses the previous bitmap loader/button class to populate lists of sequencial images, each image loader is pull in only after the previous one has loaded. The datasource for the list is taken in as an array.

It is possible to specify the number of images that should be visible within the list, or shown within the list, this is effectivly the maximum number of images that will be loaded.

The height of the component dictates the height ratio of each image shown.

[as]import mx.core.UIComponent;
import mx.utils.Delegate;
import BmpImageLoad;

class BmpImageList extends UIComponent
{
private static var symbolName:String = “BmpImageList”;
private static var className:String = “BmpImageList”;
private static var bmpImageList:MovieClip;

private var boundingBox_mc:MovieClip;

private var __arr_imageList:Array;
private var __arr_imageClips:Array;

private var __int_imagePad:Number;
private var __int_imageNumber:Number;
private var __int_loadImage:Number;
private var __bln_isVertical:Boolean;

function dispatchEvent() {};
function addEventListener() {};
function removeEventListener() {};

public function BmpImageList()
{
mx.events.EventDispatcher.initialize(this);
}

private function init():Void
{
super.init();
__arr_imageList = new Array();
__arr_imageClips = new Array();

boundingBox_mc._visible = false;
boundingBox_mc._width = width
boundingBox_mc._height = height;
}

private function size():Void
{
super.size();
boundingBox_mc._width = width
boundingBox_mc._height = height;
}

private function draw():Void
{
size();
createChildren();
}

private function createChildren():Void
{
var i:Number = 0;
var __mc_currentImageClip:MovieClip;
__int_loadImage = 0;

removeChildren();

while(i < imageList.length) { __mc_currentImageClip = createObject("BmpImageLoad", "mc_newImage"+i, getNextHighestDepth(), {_width:((width - (imagePadding*(imageNumber-1)))/imageNumber), _height:height}); __arr_imageClips[i] = __mc_currentImageClip; __arr_imageClips[i]._visible = false; __arr_imageClips[i].addEventListener("bitmapImageLoaded", Delegate.create(this, bmpLoaded)); ++i; } arrange() } private function arrange() { var i:Number = 0; while(i < imageList.length) { if(i) { __arr_imageClips[i]._x = ((((width - (imagePadding*(imageNumber-1)))/imageNumber) + imagePadding)*i); } else { __arr_imageClips[i]._visible = true; __arr_imageClips[i].loadTarget = _root.str_folderRoot + imageList[i].firstChild.nodeValue } ++i; } } private function removeChildren():Void { var i:Number = 0; while(i < __arr_imageClips.length) { destroyObject(__arr_imageClips[i]._name); ++i; } } private function bmpLoaded(obj_evnt:Object) { dispatchEvent({type:"bitmapImageLoaded",target:__arr_imageClips[__int_loadImage]}); __arr_imageClips[++__int_loadImage]._visible = true; if(!(__int_loadImage == imageList.length)) { __arr_imageClips[__int_loadImage].loadTarget = _root.str_folderRoot + imageList[__int_loadImage].firstChild.nodeValue; } else { dispatchEvent({type:"bitmapListLoaded",target:this}); } } [Inspectable (type="Array")] public function set imageList(arr_iL:Array) { __arr_imageList = arr_iL; invalidate(); } public function get imageList():Array { return __arr_imageList; } [Inspectable (type="Number", defaultValue=10)] public function set imageNumber(int_n:Number) { __int_imageNumber = int_n; invalidate(); } public function get imageNumber():Number { return __int_imageNumber; } [Inspectable (type="Number", defaultValue=10)] public function set imagePadding(int_p:Number) { __int_imagePad = int_p; invalidate(); } public function get imagePadding():Number { return __int_imagePad; } [Inspectable (type="Boolean", defaultValue=true)] public function set isVertical(bln_v:Boolean) { __bln_isVertical = bln_v; invalidate(); } public function get isVertical():Boolean { return __bln_isVertical; } }[/as] BmpImageGrid.as is effectively a control class for the number of bitmap image lists that are required to display all images in a given data source when the number of images in each list is set. Again the data source is provided as an array. It is possible to affect the height and padding of the image lists that are created within the image grid. [as]import mx.utils.Delegate; import mx.core.UIComponent; import BmpImageList; class BmpImageGrid extends UIComponent { private static var symbolName:String = "BmpImageGrid"; private static var className:String = "BmpImageGrid"; private static var bmpImageGrid:MovieClip; private var boundingBox_mc:MovieClip; private var __mc_contentHolder:MovieClip; private var __arr_imageLists:Array; private var __int_imagePad:Number; private var __int_imageNumber:Number; private var __int_rowHeight:Number; private var __int_loadImage:Number; private var __int_iRowNumber:Number; private var __bln_autoSize:Boolean; function dispatchEvent() {}; function addEventListener() {}; function removeEventListener() {}; public function BmpImageGrid() { mx.events.EventDispatcher.initialize(this); } private function init():Void { super.init(); __arr_imageLists = new Array(); boundingBox_mc._visible = false; boundingBox_mc._width = width boundingBox_mc._height = height; } private function size():Void { super.size(); boundingBox_mc._width = width boundingBox_mc._height = height; } private function draw():Void { size(); createChildren(); } private function getImageCellDims():Void { var int_minRow:Number = Math.ceil(imageList.length/imageNumber); __int_iRowNumber = Math.max((height / rowHeight), int_minRow); if(autoSize)setSize(width, (rowHeight + imagePadding)); dispatchEvent({type:"gridDimensionsSet",target:this}); } private function createChildren():Void { getImageCellDims() removeChildren(); __mc_contentHolder = createEmptyMovieClip("mc_contentHolder", 0); var __mc_currentImageRow:MovieClip; var i:Number = 0; var int_arrSplice:Number var tmp_arrImages:Array; __int_loadImage = 0; while(i < __int_iRowNumber) { int_arrSplice = (imageNumber*i); tmp_arrImages = imageList.slice(int_arrSplice, (int_arrSplice+imageNumber)); __mc_currentImageRow = createObject("BmpImageList", "mc_newBmpImgList"+i, i, {_width:width, _height:rowHeight, imageNumber:imageNumber, imagePadding:imagePadding}); __mc_currentImageRow._visible = false; __mc_currentImageRow.addEventListener("bitmapListLoaded", Delegate.create(this, bmpRowLoaded)); __mc_currentImageRow.addEventListener("bitmapImageLoaded", Delegate.create(this, bmpLoaded)); if((int_arrSplice+imageNumber) > imageList.length) __int_iRowNumber = ++i;
++i;
}
arrange();
}

private function arrange()
{
var i:Number = 0;
var int_arrSplice:Number
var __mc_currentImageRow:MovieClip;

while(i < __int_iRowNumber) { int_arrSplice = (imageNumber*i); __mc_currentImageRow = this["mc_newBmpImgList"+i]; if(i) { __mc_currentImageRow._y = (rowHeight + imagePadding) *i; } else { __mc_currentImageRow._visible = true; __mc_currentImageRow.imageList = imageList.slice(int_arrSplice, (int_arrSplice+imageNumber)); } ++i; } } private function bmpClicked(obj_evnt:Object) { dispatchEvent({type:"click",target:obj_evnt.target}); } private function bmpLoaded(obj_evnt:Object) { obj_evnt.target.useHandCursor = true; obj_evnt.target.addEventListener("click", Delegate.create(this, bmpClicked)); } private function bmpRowLoaded(obj_evnt:Object) { if(autoSize)setSize(width, ((rowHeight + imagePadding) * (__int_loadImage+2))); dispatchEvent({type:"bitmapListLoaded",target:this}); ++__int_loadImage if(!(__int_loadImage == __int_iRowNumber)) { this["mc_newBmpImgList" + (__int_loadImage)]._visible = true; var int_arrSplice:Number = (imageNumber*__int_loadImage); this["mc_newBmpImgList"+__int_loadImage].imageList = imageList.slice(int_arrSplice, (int_arrSplice+imageNumber)); } else { if(autoSize)setSize(width, ((rowHeight + imagePadding) * (__int_loadImage))); dispatchEvent({type:"bitmapGridLoaded",target:this}); } } private function removeChildren():Void { var i:Number = 0; while(i < __int_iRowNumber) { destroyObject(this["mc_newBmpImgList"+i]) ++i; } __mc_contentHolder.removeMovieClip(); } [Inspectable (type="Array")] public function set imageList(arr_iL:Array) { __arr_imageLists = arr_iL; invalidate(); } public function get imageList():Array { return __arr_imageLists; } [Inspectable (type="Number", defaultValue=35)] public function set rowHeight(int_n:Number) { __int_rowHeight = int_n; invalidate(); } public function get rowHeight():Number { return __int_rowHeight; } [Inspectable (type="Number", defaultValue=10)] public function set imageNumber(int_n:Number) { __int_imageNumber = int_n; invalidate(); } public function get imageNumber():Number { return __int_imageNumber; } [Inspectable (type="Number", defaultValue=10)] public function set imagePadding(int_p:Number) { __int_imagePad = int_p; invalidate(); } public function get imagePadding():Number { return __int_imagePad; } [Inspectable (type="Boolean", defaultValue=true)] public function set autoSize(bln_aS:Boolean) { __bln_autoSize = bln_aS; invalidate(); } public function get autoSize():Boolean { return __bln_autoSize; } }[/as]

One thought on “Flash 8 Photo gallery AS”

Comments are closed.