photo load order mess up as3 - actionscript-3

I have created a container(or a movieclip) that will add the photos in order and display on the stage. however, because of the different file size, it will add the smallest file size photo first. how i can solve this issue. please see the sample code below
// image0.jpg -> 3k
// image1.jpg -> 2k
// image2.jpg -> 1k
// image3.jpg -> 2k
// image5.jpg -> 1k
var photoPath:Array = new Array();
var photoContainer:MovieClip = new MovieClip();
photoPath.push('image0.jpg');
photoPath.push('image1.jpg');
photoPath.push('image2.jpg');
photoPath.push('image3.jpg');
photoPath.push('image4.jpg');
for(var i = 0; i < photoPath.length; i++)
{
var loader:Loader = new Loader();
loader.load(URLRequest(photoPath[i]));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, photoLoaded);
}
function photoLoaded(e:Event):void
{
photoContainer.addChild(e.target.content);
}
//output will looks like (image2,image5,image1,image3,image0) instead of 0,1,2,3,4,5

There are quite a few ways to handle this issue, probably the easiest way to retrofit your current code is to add the Loader to the displaylist as it is instantiated. This will guarantee that they're placed in the photoContainer in the correct order. If you absolutely need the bitmap itself to be in the displaylist as opposed to the loader itself, you can address this in your photoLoaded method:
import flash.display.Loader;
var photoPath:Array = new Array();
var photoContainer:MovieClip = new MovieClip();
photoPath.push('image0.jpg');
photoPath.push('image1.jpg');
photoPath.push('image2.jpg');
photoPath.push('image3.jpg');
photoPath.push('image4.jpg');
for(var i = 0; i < photoPath.length; i++)
{
var loader:Loader = new Loader();
photoContainer.addChild(loader); //add the loader to photoContainer
loader.load(new URLRequest(photoPath[i]));
//you only actually have to listen for complete below if you want to replace the loader with its contents
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, photoLoaded);
}
function photoLoaded(e:Event):void
{
var loader:Loader = e.target.loader;
var index:int = photoContainer.getChildIndex(loader);
// this will add the contents of the loader in the same order the loader was originally added
photoContainer.addChildAt(loader.content, index);
photoContainer.removeChild(loader);
}

Simply loads and adds the photos to the container in the order given in the array:
var photoPath:Array = new Array();
var photoContainer:MovieClip = new MovieClip();
var i:int = 0;
photoPath.push('image0.jpg');
photoPath.push('image1.jpg');
photoPath.push('image2.jpg');
photoPath.push('image3.jpg');
photoPath.push('image4.jpg');
loadPhoto(i);
function loadPhoto(i:int):void
{
var loader:Loader = new Loader();
loader.load(new URLRequest(photoPath[i]));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, photoLoaded);
}
function photoLoaded(e:Event):void
{
photoContainer.addChild(e.target.content);
trace(e.target.url); // Verify
if(i<photoPath.length-1) loadPhoto(++i);
}
Output:
image0.jpg
image1.jpg
image2.jpg
image3.jpg
image4.jpg

Related

How to get index of a Bitmap Image from bitmapdata(from an Array)?

I am wondering if i have an Array that push content that is Bitmap, how do i get index of a specific image when clicked. I tried to use indexOf but no luck, my codes are below.
Thanks for your time!
Code:
//First Part is where i add the URLRequest and add the image into contentHolder then onto Stage
function loadImage():void {
for(var i:int = 5; i < somedata.length; i++){
if(somedata[i]){
var loader:Loader = new Loader();
loader.load(new URLRequest("http://www.rentaid.info/rent/"+somedata[i]));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
}
}
}
function onImageLoaded(e:Event):void {
loadedArray.push(e.target.content as Bitmap);
for(var i:int = 0; i < loadedArray.length; i++){
var currentY1:int = 200;
e.currentTarget.loader.content.height =200;
e.currentTarget.loader.content.y += currentY1;
currentY1 += e.currentTarget.loader.content.height +300;
_contentHolder.mouseChildren = false; // ignore children mouseEvents
_contentHolder.mouseEnabled = true; // enable mouse on the object - normally set to true by default
_contentHolder.useHandCursor = true; // add hand cursor on mouse over
_contentHolder.buttonMode = true;
_contentHolder.addChild(loadedArray[i]);
addChild(_contentHolder);
_contentHolder.addEventListener(MouseEvent.CLICK, gotoscene);
}
}
// then the part where i try to get the index
function gotoscene(e:MouseEvent):void {
var index:Number;
index = loadedArray.indexOf(e.target);
trace(index);
}
Edit:
var viewport:Viewport = new Viewport();
viewport.y = 0;
viewport.addChild(_contentHolder);
Your first question has very simple answer:
var image:Bitmap = new Bitmap();
var images:Array = new Array(image);
for (var i:uint = 0; i < images.length; i++) {
// images[i].bitmapData is the original image in your array
// image.bitmapData is searched one
if (images[i].bitmapData == image.bitmapData) {
// found
}
}
But your problem is bigger than this. I see you keep wandering around..
You should add listener to each child, not the content holder as one. I usually don't use Loaders, but get their Bitmaps and wrap them in Sprites or something, that I add into the scene. You should store either this Sprite or your Loader into that array, not the Bitmap. Then add listener to each of them (Sprite or Loader, not Bitmap) and get the target. Depending on what you've stored in the array, you can easily get it as:
function gotoscene(e:MouseEvent):void {
var index:uint = loadedArray(indexOf(e.target));
}
But it's important to store one specific type that will actually be clickable. Don't think about the Bitmap - it's only a graphic representation, and doesn't do much in the code.
**EDIT:
Okay I'm adding the code you need but it's important to understand what you are doing and not just rely on someone else's answer :)
function onImageLoaded(e:Event):void {
var bitmap:Bitmap = e.target.content as Bitmap; // get the Bitmap
var image:Sprite = new Sprite();
image.addChild(bitmap); // wrap it inside new Sprite
// add listener to Sprite!
image.addEventListener(MouseEvent.CLICK, gotoscene);
// gets url of current image (http://website.com/images/image1.jpg)
var url:String = e.target.loaderURL;
// get only the number from that url by replacing or by some other way
// this removes the first part and results in "1.jpg"
var name:String = url.replace("http://website.com/images/image", "");
// this removes the extension and results in number only - 1, 2, 3
// it's important to change this depending on your naming convention
name = name.replace(".jpg", "");
image.name = "button" + name; // results in "button1", "button2", "button3"
// store object, name, or whatever (not really needed in your case, but commonly used)
loadedArray.push(image.name);
image.x = counter * 100; // position so you can see them, at 100, 200, 300, etc.
_contentHolder.addChild(image); // add newly created Sprite to content
}
function gotoscene(e:MouseEvent):void {
var name:String = e.target.name;
// strips down "button" from "button1", and only the number remains,
// which is 1, 2, 3, etc. the number of the scene :)
var scene:uint = name.replace("button", "");
// you're the man now :)
}

How can I access the width of a JPG loaded inside a movieclip in AS3?

i'm trying to reproduce the bookshelf similar the one in this site: http://www.callis.com.br/
The books are PNG files that comes in several different sizes.
What I'm trying to accomplish is, after loading in several different movieclips (book0, book1, book2, ...) read their widths, calculate the gap necessary to push it, and then arrange the x value of each book.
Every time I try to access the width value, it says it's 0.
Here's a portion of my code, that's trying to do the trick.
Thanks in advance.
for (j=0; j < dados.livro.length(); j++){
if(j<8){
targetLivro = MovieClip(MovieClip(root).livros.getChildByName("livro"+(j)));
}else{
targetLivro = MovieClip(MovieClip(root).getChildByName("livro"+(j)));
}
preparaLivro(targetLivro,dados.livro[j].imagem.text(),dados.livro[j].link.text());
//larguraTotalLivrosSup += targetLivro.width;
//trace(larguraTotalLivrosSup);
trace("livro"+j+": ");
trace("título:"+dados.livro[j].titulo.text());
trace("imagem:"+dados.livro[j].imagem.text());
trace("link:"+dados.livro[j].link.text());
}
//organiza a primeira estante
//
/*
for (i=0; i<largurasArray.length; i++){
trace(largurasArray[i]);
}*/
var offset:Number = 20;
for (j=0; j<livros.numChildren; j++){
//targetLivro = MovieClip(livros).getChildByName("livro"+(j));
trace(livros.getChildAt(j).width);
}
function preparaLivro(livro:MovieClip, capa:String, url:String){
var capaLoader:Loader = new Loader();
var capaImageRequest:URLRequest = new URLRequest(capa);
var capaBitmapData:BitmapData;
var capaBitmap:Bitmap;
var capaLargura:Number = 0;
capaLoader.load(capaImageRequest);
capaLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void{
capaBitmapData = new BitmapData(e.target.content.width, e.target.content.height);
capaBitmapData.draw(capaLoader);
capaBitmap = new Bitmap;
capaBitmap.bitmapData = capaBitmapData;
livro.y -= e.target.content.height;
trace(e.target.content.width, e.target.content.height);
livro.buttonMode = true;
livro.addChild(capaBitmap);
livro.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void{
navigateToURL(new URLRequest(url), "_blank");
});
//trace(e.target.content.width);
});
}
Instantiate bitmap from LoaderInfo(event.target).content like:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest("http://www.google.com/images/srpr/logo4w.png"));
function onComplete(event:Event):void
{
var bitmapData:BitmapData =
Bitmap(LoaderInfo(event.target).content).bitmapData;
}
Tracing bitmapData.width and bitmapData.height outputs:
width: 550, height: 190
Otherwise, if you want width / height from the loader, access loader's contentLoaderInfo:
var width:Number = loader.contentLoaderInfo.width;
var height:Number = loader.contentLoaderInfo.height;

Modify dynamic created objects that are saved in an array

i have multiple images that are created dynamically, and i want in some cases to change the image. i can save them in an array, but how can i change the image (load another image) by getting it from the array.
let's say that i have an array:
var ImagesArray:Array = [];
and i push to it loader objects, and want to change (load new) image of ImagesArray[0] or ImagesArray[1]... like:
var loaderNew:Loader = new Loader();
loaderNew = ImagesArray[i];
loaderNew.load(new URLRequest("../lib/NewImg.png"));
Thanks,
You dont need to create new loader if you only want to change its image, here's an example of function to update image url:
private function changeImageByIndex(i:int, url:String):void
{
var loader:Loader = ImagesArray[i] as Loader;
if (!loader)
{
loader = new Loader();
addChild(loader);
ImagesArray[i] = loader;
}
loader.load(new URLRequest(url));
}
If you have bitmap, use loadBytes() method instead load(), here's example:
var bitmap:Bitmap = new Bitmap(new BitmapData(100, 100, true, 0xff0000));
var encoder:JPEGEncoder = new JPEGEncoder();
loader.loadBytes(encoder.encode(bitmap.bitmapData));

eventlistener doesn't execute its function

I need to put some thumbnails on the stage. they have different width and I need to get the width after They are loaded.I used the listener to find the width but the function which listener should call doesnt run.
why my code doesn't enter to the function of loadThumbs?
function makeScroller():void
{
for (var item:uint = 0; item < 7; item++ )
{
var thisOne:MovieClip = new MovieClip();
var blackBox:Sprite = new Sprite();
var thisThumb:Sprite = new Sprite();
var imageLoader:Loader = new Loader();
imageLoader.load(new URLRequest(thumbList[item]));
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadThumbs);
function loadThumbs (e:Event):void
{
blackBox.graphics.beginFill(0xFFFFFF);
blackBox.graphics.drawRect(-1,-1,imageLoader.width,imageLoader.height);
thisOne.addChild(blackBox);
thisOne.blackBox = blackBox;
thisOne.x = tsX;
thisThumb.addChild(imageLoader);
thisOne.addChild(thisThumb);
tsX += imageLoader.width;
scroller.addChild(thisOne);
}
}
}
I have just tried a more simplified version of your code without any issues, maybe try this:
NOTE: Best practice is to add the COMPLETE listener BEFORE you call load also...
function makeScroller():void
{
var imageLoader:Loader = new Loader();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadedHandler);
imageLoader.load(new URLRequest("http://images.imagecomics.com/c/2012/IMG120350.jpg"));
function loadedHandler(e:Event):void
{
trace("loaded");
}
}
makeScroller();

as3 moving image from one mc to another

With the code below I created some imgMcA and some imgMcB then I loaded images into imgMcA ones. ImgMcBs have no image at that moment. So if one of imgMcA is clicked the image should be transferred to one of the empty imgMcBs (may be randomly) and if imgmcB is clicked later the image should move back to its imgMcA back. I could not find out how I can accomplish this.
Thanks in advance
function imageList(mcname, img, index){
var imgMcA:MovieClip=new MovieClip();
imgMcA.graphics.beginFill(0x000000);
imgMcA.graphics.drawRect(0,0,imgWidth,imgHeight);
imgMcA.graphics.endFill();
imgMcA.name=lemma;
imgMcA.addEventListener(MouseEvent.CLICK, moveImage);
var imgMcB:MovieClip=new MovieClip();
imgMcB.graphics.beginFill(0x000000);
imgMcB.graphics.drawRect(0,0,imgWidth,imgHeight);
imgMcB.graphics.endFill();
imgMcB.name=index;
addChild(imgMcB);
var imgLoader:Loader = new Loader();
imgLoader.load(new URLRequest(img));
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, changeProperties);
imgLoader.mouseEnabled=false;
imgMcA.addChild(imgLoader);
}
function moveImage(evnt:MouseEvent){
}
You could linked mcA & mcB by adding them to the same parent.
function createBlock():void
{
var imgLoader:Loader = new Loader();
//add the loading code here...
var mcA:Sprite = new Sprite();
var mcB:Sprite = new Sprite();
// add Click event listeners for both Mcs here...
var parent:Sprite = new Sprite();
//add Children
parent.addChild(mcA);
parent.addChild(mcB);
addChild(parent);
}
function mouseClickHandler(event:MouseEvent)
{
var dispatcher:Sprite = event.currentTarget as Sprite;
//if you added a Loader to it
if( dispatcher.numChildren > 0)
{
//retrieve the image
var img:Loader = dispatcher.getChildAt(0);
//identify the parent
var parent:Sprite = dispatcher.parent;
var index:int = parent.getChildIndex(dispatcher);
//identify the receiving MC
//of course this only works with two children!!!
if(index > 0)
var receiver:Sprite = parent.getChildAt(0) as Sprite;
else
receiver = parent.getChildAt(1) as Sprite;
//add the image to the other MC
receiver.addChild(img);
}
}
The rest is not too complicated to achieve. You will need to use a Boolean and add a TextField. If the TextField contains text, set the Boolean to true.
It may be worth looking at Classes or you could use an Object as a container for the MovieClips, the TextField and the Boolean, although a Class will give you more flexibility...
With a Class, you wouldn't have to iterate in order to find what does what. Your Click listener would look something like this:
private function mouseClickHandler(event:MouseEvent)
{
receiver.addChild( image );
if( hasText)
imageReturn();
}