I am using Ben Cline’s xml grid gallery. I sliced a single image into 48 thumbs, 6 rows, 8 columns.
The one issue I have is that only 47 thumbs out of the 48 display. The bottom right corner is empty even though there is a 48th image that has loaded. I have pored over the AS but can not figure out why. I did notice in Ben’s example he had an odd number of thumbs, 25 to be exact and his ended with one thumb in the last column.
// ===============================================================================================================================================
// code by Ben Cline November, 2006 - http://www.bencline.net
// ===============================================================================================================================================
import mx.transitions.Tween;
import mx.transitions.easing.*;
import flash.filters.BlurFilter;
// ===============================================================================================================================================
// + + + VARIABLES + + + + + +
// ===============================================================================================================================================
var path : String = "photos.xml"; // path used for the xml, but for source code, I've included the xml file
var xmlThumb : String; // url for the thumbnails
var thumbString : String = "LOADING THUMBNAILS"; // string called before the first thumbnail is loaded
var dupThumb : String;
var s : Number = 0; // spacing between the thumbnails
var rows : Number = 8; // number of rows
var curr : Number = 0; // current thumb
var currAn : Number = 0; // var for counting through the animation sequences
var cols : Number = 6; // number of columns
var tW : Number = 50; // thumb width
var tH : Number = 50; // thumb height
var xP : Number = 0; // x position
var yP : Number = 0; // y position
var xR : Number; // random x position
var yR : Number; // random y position
var r_w_h : Number; // random width and height
var tN : Number; // total nodes from xml
var l : Number; // bytes loaded
var t : Number; // bytes total
var percent : Number; // percent loaded
var tweenRate : Number = 0.2; // tween rate for the thumbs
var blur : Number;
var tweenProp : Number; // tween proportion that will be subtracted from the tween rate
var newBlur : BlurFilter;
var gridXML : XML; // xml object
var temp_mc : MovieClip; // temporary movie clip for loading purposes
var thumbHolder : MovieClip = this.createEmptyMovieClip("holder_mc", this.getNextHighestDepth()); // movie clip that holds all the thumbnails
var mc : MovieClip = this.createEmptyMovieClip("mc", this.getNextHighestDepth()); // mc for the loaded images, that will show up when you click something
var thumb : MovieClip; // movie clip that holds the movie clip that the thumb will be loaded into
var button : MovieClip; // movie clip that the thumb will be loaded into
var tA : Array = new Array(); // thumb array, that will be tweened
var mA : Array = new Array(); // movie clip array that holds the mc's that the thumbs will be loaded into
var xPA : Array = new Array(); // x position array
var yPA : Array = new Array(); // y position array
var xRA : Array = new Array(); // random x position array
var yRA : Array = new Array(); // random y position array
var r_w_h_array : Array = new Array(); // random width, height array
var blurArray : Array = new Array();
var filterArray : Array = new Array();
var path_a : Array = new Array(); // path to the file array
var tweenThumb_h: Tween; // tween the thumb height object
var tweenThumb_w: Tween; // tween the thumb width object
var tweenThumb_x: Tween; // tween the thumb x position object
var tweenThumb_y: Tween; // tween the thumb y position object
var tweenThumb_a: Tween; // tween the thumb alpha object
var myTween : Tween; // tween for blurs
var textFormat : TextFormat = new TextFormat(); // text format object
var thumbText : TextField = this.createTextField("thumbText", this.getNextHighestDepth(), -20, -20, 0, 0, 10); // new textfield to show how many thumbnails have been loaded
// ===============================================================================================================================================
// + + + TEXT FORMATTING + + + + + +
// ===============================================================================================================================================
thumbText.antiAliasType = "advanced";
textFormat.color = 0x000000;
textFormat.font = "Verdana";
textFormat.size = 10;
thumbText.autoSize = true;
thumbText.border = false;
thumbText.type = "static";
thumbText.multiline = false;
thumbText.text = thumbString;
thumbHolder._x = 20;
thumbHolder._y = thumbText._y+thumbText._height+10;
// ===============================================================================================================================================
// + + + XML ON LOAD + + + + + +
// ===============================================================================================================================================
gridXML = new XML();
gridXML.ignoreWhite = true;
gridXML.load(path);
mc._y = 300;
mc._x = 20;
gridXML.onLoad = setUpGrid;
function setUpGrid():Void {
tN = gridXML.firstChild.childNodes[0].childNodes.length; // get the total nodes from the xml
cols = Math.ceil(tN/rows); // divide the number of total nodes by the number of rows set up, rounded up to the nearest integer
tweenProp = tweenRate/(tN+10); // get the proportion of the tween rate, so we can speed up the tweens of the thumbs in, every time a new thumb is loaded
thumbText.text = "0 / "+tN+" THUMBNAILS LOADED"; // set up the text, initially there are 0 out of how ever many thumbs there are to be loaded
for (var i = 0; i<tN; i++) { // okay the fun part, in order to set up a grid layout, we have to have 2 nested for loops, don't ask why...., the first we loop through the total number of nodes
for (var r = 0; r<rows; r++) { // then we loop through the total number of rows
for (var c = 0; c<cols; c++) { // lastly we loop through the total number of columns
thumb = thumbHolder.createEmptyMovieClip("thumb_mc"+i, i); // while looping, we need to create empty movie clips to hold the thumbs, this movie clip will be used as the button
button = thumb.createEmptyMovieClip("button_mc"+i, i); // this movie clip we will eventually load thumbs into
xmlThumb = gridXML.firstChild.childNodes[0].childNodes*.attributes.thumb; // get all the urls of the thumbnails
if (xmlThumb !== undefined) { // make sure that none of the urls are undefined, which basically means there will be undefined urls if there is not
// a clean divide of rows by the total number of columns
thumb._alpha = 0; // set the initial opacity to zero
thumb._visible = false;
xP = Math.ceil((s+tW)*r); // okay here we determine our x value on the grid for a thumb, basically we're adding the spacing to the thumb width and then multiplying
// that by our current r variable which is whatever r is at this point in time in our loop
yP = Math.ceil((s+tH)*c); // this is the same as above only it holds the y value in our grid
xR = Math.ceil(Math.random()*Stage.width); // here we get a random x value where we will eventually animate our thumbs from
yR = Math.ceil(Math.random()*Stage.height); // this is the same as above only it is the y value
blur = Math.random()*Stage.width;
r_w_h = Math.ceil(Math.random()*Stage.width); // variable that gives a random width and height to work with
tA.push(thumb); // okay, push the thumb movie clip into an array that will be used for animating
mA.push(button); // push the button movie clip which remember is an empty movie clip inside the thumb movie clip that we will load our images into
xPA.push(xP); // push the x position in the grid to an array
yPA.push(yP); // push the y position in the grid to an array
xRA.push(xR); // push the x random position into an array
yRA.push(yR); // "" "" y "" "" "" "" ""
r_w_h_array.push(r_w_h); // push the random width and height into an array
path_a.push(xmlThumb); // push the urls of thumbs into an array
blurArray.push(blur);
i++; // okay for this nested to work, we have increment the i value which is the current number we're on of the total nodes
if (i == tN-1) { // once i has reach the end
loadThumb(path_a[curr], mA[curr]); // load the first node
break; // we have to break the for loop as well
}
}
}
}
}
}
// ===============================================================================================================================================
// + + + THUMB LOADER + + + + + +
// ===============================================================================================================================================
// function requires 2 parameters, the url of the thumb, and movie clip we need to load the thumb into
function loadThumb(path_url:String, mc:MovieClip) {
mc.loadMovie(path_url); // load the thumb into the movie clip
temp_mc = _root.createEmptyMovieClip("temp_mc", _root.getNextHighestDepth()); // create a temporary movie clip to handle our onEnterFrame event
temp_mc.onEnterFrame = function() {
l = mc.getBytesLoaded(); // get the bytes loaded
t = mc.getBytesTotal(); // get the bytes total
percent = l/t; // get the percent between the two
if (percent>=1) { // if the percent is greater to our equal to 1, this means the thumbnail is loaded
curr++;
if(curr <= tN-1) {
loadThumb(path_a[curr], mA[curr]);
thumbText.text = (curr+1)+" / "+tN+" THUMBNAILS LOADED";
}
else {
thumbText.text = (curr--)+" / "+tN+" THUMBNAILS LOADED";
animate(tA[currAn], xRA[currAn], xPA[currAn], yRA[currAn], yPA[currAn], r_w_h_array[currAn], blurArray[currAn]);
}// for a little extra flare, lets animate the thumb into the grid from a random position
// set up the text properly
temp_mc.removeMovieClip(); // delete the onEnterFrame event
}
};
}
// ===============================================================================================================================================
// + + + ENABLE BUTTON STATES + + + + + +
// ===============================================================================================================================================
function enableButtons():Void {
// okay note that when we need to access all of the thumbs at once and we are outside the initial for loop, we have create another one
for (var i = 0; i<tN; i++) {
// this provides the unique identifier to each thumbnail, which is critical for this to work
var thumb:MovieClip = thumbHolder["thumb_mc"+i];
dupThumb = gridXML.firstChild.childNodes[0].childNodes*.attributes.thumb;
thumb.i = i;
thumb.dupThumb = dupThumb;
// rollover state
thumb.onRollOver = function():Void {
// okay the way I set this up is when a thumb is rolled over, all of the other thumbs dim out, order to access all the other thumbs
// we must create another for loop
for (var i = 0; i<tN; i++) {
// same as earlier, provides identification for the correct thumb
var thumb:MovieClip = thumbHolder["thumb_mc"+i];
// okay this refers to the current thumb being rolled over, and if this is not equal to our identifiers above, lets dim them out
if (thumb !== this) {
new Tween(thumb, "_alpha", Strong.easeOut, thumb._alpha, 50, .5, true); // tween the opacity down of the other thumbs
}
}
};
// rollout state, same as above, only we tween all the other button alphas back to normal again
thumb.onRollOut = function():Void {
for (var i = 0; i<tN; i++) {
var thumb:MovieClip = thumbHolder["thumb_mc"+i];
if (thumb !== this) {
new Tween(thumb, "_alpha", Strong.easeOut, thumb._alpha, 100, .5, true);
}
}
};
thumb.onRelease = function():Void {
mc.loadMovie(this.dupThumb);
}
}
}
// ===============================================================================================================================================
// + + + ANIMATE THUMBNAIL + + + + + +
// ===============================================================================================================================================
// function requires 6 parameters, a movie clip, a random x position, an x position in the grid, a random y position, a y position in the grid, and random width/height
function animate(thumbnail:MovieClip, randomX:Number, xPosition:Number, randomY:Number, yPosition:Number, width_height:Number, blurAmount:Number) {
var myTween:Tween = new Tween(thumbnail, "blur", Strong.easeOut, blurAmount, 0, tweenRate, true);
myTween.onMotionChanged = function() {
thumbnail.filters = [new BlurFilter(thumbnail.blur, thumbnail.blur, 1)];
}
myTween.onMotionFinished = function() {
new Tween(thumbnail, "blur", Strong.easeOut, blurAmount, 0, tweenRate, true);
}
thumbnail._visible = true;
tweenThumb_w = new Tween(thumbnail, "_width", Strong.easeOut, width_height, tW, tweenRate, true);
tweenThumb_h = new Tween(thumbnail, "_height", Strong.easeOut, width_height, tH, tweenRate, true);
// tween the alpha in
tweenThumb_a = new Tween(thumbnail, "_alpha", Strong.easeOut, thumbnail._alpha, 100, tweenRate, true);
// tween the x position from the random one to the one on the grid
tweenThumb_x = new Tween(thumbnail, "_x", Strong.easeOut, randomX, xPosition, tweenRate, true);
// tween the y position from the random one to the one on the grid
tweenThumb_y = new Tween(thumbnail, "_y", Strong.easeOut, randomY, yPosition, tweenRate, true);
tweenThumb_y.onMotionFinished = function():Void {
currAn++;
if(currAn <= tN-1 && path_a[currAn] !== undefined) {
tweenRate += -(tweenProp);
animate(tA[currAn], xRA[currAn], xPA[currAn], yRA[currAn], yPA[currAn], r_w_h_array[currAn], blurArray[currAn]);
}
else {
enableButtons();
}
}
}