I don't like the Wonder Wall effect in Flash, but a lot of designers love it. And if you work in a company that have one of these designers… I found a nice code shared by Flashmonkey in order to code this Flash effect. But this code runs only for an image from the Flash library. Obviously the designer told me that he wants to load tons of external images. So let's modify the code.
STEP 1. Load some external images.
In the file "Application.as" we found the code. The code loads a bitmap and distort it. So the first thing we must do is to change the bitmap loaded from Flash library with an array of bitmaps externally loaded. We create the array with the image names, and change the BitmapData variable to an array of BitmapData:
private var bmd:Array=new Array(); //THIS WAS private var bmd:BitmapData;
private var imagenes:Array=new Array("mono1.jpg","mono2.jpg","mono3.jpg","mono4.jpg","mono5.jpg","mono6.jpg","mono7.jpg","mono8.jpg","mono9.jpg");
Next, find the line:
bmd = new Monkey(100, 100);
Monkey is a simple class to name the bitmap from library. We need to change this class to a class that loads an image externally, so we will need a class named "bitmap":
----bitmap.as----
package
{
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
public class bitmap extends Sprite
{
private var _url:String = "";
private var _bytesLoadProgress:int = 0;
private var _loaded:Bitmap;
private var _loadedBData:BitmapData;
public function bitmap(url:String)
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressLoaded);
loader.load(new URLRequest(url));
}
public function onComplete(e:Event):void
{
_loadedBData = new BitmapData(100,100);
_loadedBData = e.target.loader.contentLoaderInfo.content.bitmapData.clone();
_loaded = new Bitmap(_loadedBData);
this.addChild(_loaded);
dispatchEvent(new Event("cargado"));
}
public function progressLoaded(e:ProgressEvent):void
{
_bytesLoadProgress = e.bytesLoaded/e.bytesTotal;
}
public function getProgress():int
{
return _bytesLoadProgress;
}
public function getBitmapData():BitmapData
{
return _loadedBData;
}
}
}
This class loads the image and dispatches the event "cargado" (loaded) when the image has been loaded. So now we are going to change the previous line to:
for(i = 0; i < imagenes.length; i++) //THIS WAS bmd = new Monkey(100, 100);
{
bmd.push(new bitmap(imagenes[i]));
bmd[i].addEventListener("cargado", estaCargado, false, 0, true);
}
And in the loaded image event we count the images loaded, to know when the last image ends its loading, and in that moment, we start the animation
private function estaCargado (evt:Event):void {
evt.target.removeEventListener("cargado", estaCargado);
counterLoader++;
if (counterLoader==imagenes.length)
addEvent(this, Event.ENTER_FRAME, draw);
}
Now, the last modification will be calling the distort object, we will pass the array to it:
distort.setTransform(img, bmd[i].getBitmapData(), images[i].tl.point, images[i].tr.point, images[i].br.point, images[i].bl.point);
STEP 2. Load some external images, BUT NOT HARDCODED IN THE SCRIPT.
Ok, its ugly to have the images in an array, so let's load them with an XML. So we create the XML, with "images" as the root node and "image" as the element nodes. Next, we define the code:
private var myXMLLoader:URLLoader = new URLLoader();
private var imagenes:Array=new Array();
Now we need to load the XML at the beginning of the "added" function, below the
if(showGuides) addChild(mouseGuide);
line , and define the number of image points depending on the number of images loaded.
myXMLLoader.load(new URLRequest("images.xml"));
myXMLLoader.addEventListener(Event.COMPLETE, processXML);
And then continue the "added" function in the "processXML" function. We will use a two rows image wall, so the number of images would be a multiple of 2.
private const wh:uint=2; //NUMBER OF ROWS
…….
private function processXML(e:Event):void {
var xmlFull:XML = new XML(e.target.data);
xmlFull.ignoreWhite = true;
myXMLLoader.removeEventListener(Event.COMPLETE, processXML);
myXMLLoader = null;
for (var i:uint=0; i<xmlFull.descendants("image").length(); i++) {
imagenes.push(xmlFull.descendants("image")[i]);
}
var hw:uint=imagenes.length/wh;
var layout:Array = [];
var xpos:int = 150;
var ypos:int = 150;
var w:int;
var h:int;
for(w = 0; w <= wh; w++)
{
layout[w] = [];
for(h = 0; h <= hw; h++)
{
var point:ImagePoint = new ImagePoint();
point.x = point.ox = xpos;
point.y = point.oy = ypos;
point.maxDist = maxDist;
points[points.length] = point;
layout[w][h] = point;
xpos += IMAGEWIDTH;
}
xpos = 150;
ypos += IMAGEWIDTH;
}
var l:int = layout.length-1;
var i2:int;
var l2:int;
var imgPoints:ImagePoints;
counterLoader=0;
for(i = 0; i < l; i++)
{
l2 = layout[i].length-1;
for(i2 = 0; i2 < l2; i2++)
{
imgPoints = new ImagePoints(layout[i][i2], layout[i][i2+1], layout[i+1][i2+1], layout[i+1] [i2]);
imgPoints.color = Math.random() * 0xCCCCCC;
images[images.length] = imgPoints;
}
}
for(i = 0; i < imagenes.length; i++)
{
bmd.push(new bitmap(imagenes[i]));
bmd[i].addEventListener("cargado", estaCargado, false, 0, true);
}
distort = new DistortImage(250, 250);
}
STEP 3. I want to know the image number who has the mouse over
There are some methods to achieve this. We are going to code an easy method, using Rectangle objects. When we are filling the "images" array, we will fill a Rectangles array too:
for(i2 = 0; i2 < l2; i2++)
{
imgPoints = new ImagePoints(layout[i][i2], layout[i][i2+1], layout[i+1][i2+1], layout[i+1][i2]);
imgPoints.color = Math.random() * 0xCCCCCC;
images[images.length] = imgPoints;
imagerectangles.push(new Rectangle(layout[i][i2].x, layout[i][i2].y, Math.abs(layout[i] [i2+1].x - layout[i][i2].x), Math.abs(layout[i][i2].y-layout[i+1][i2+1].y)));
}
Each Rectangle class will hold the position of each image. So now we only need to use the Contains method to see if the mouse is over certain image. We will use a Number variable "zNum" that will hold the mouse-over image number every time. In the "draw" method:
for(i = 0; i < l; i++)
{
if (imagerectangles[i].contains(mouseX,mouseY) ) {
zNum=i;
}
distort.setTransform(img, bmd[i].getBitmapData(), images[i].tl.point, images[i].tr.point, images[i].br.point, images[i].bl.point);
}
And the mouse events? The sprite on which all the graphics are drawn is "imgSprite", so add the events to it:
imgSprite.buttonMode = true;
imgSprite.addEventListener(MouseEvent.CLICK, clicked);
and now the function "clicked" will tell us the value of the "zNum" variable:
private function clicked(event:MouseEvent):void {
trace(String(zNum));
}
yannb
admin
Gerard Garcia
Gerard Garcia
Andres
Jumbosana