Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
solraun

Images start loading prioritizing -> multiple images loading

Recommended Posts

Hi,

 

I'm using LoaderMax to load the Images for a Photographers Portfolio.

 

First, I create a LoaderMax instance, then add every Image to it with a separate ImageLoader each. Then I start to load the queue.

I am not showing the pictures with the ImageLoader, but with a single UILoader by changing the URL it points to.

 

Now I got a problem with prioritizing:

 

To keep the experience as smooth as possible, I need to change the queue order often. (Thats why I use LoaderMax)

For example, I want to change the top 3 Items of the queue to the following: x y z

for this i prioritize z, then y, then x. Assuming it would order th queue x y z.

That works, the Problem is: He then starts to load all of them simultaneously, which triples the loading time.

I want it to fully load x, then fully load y, then fully load z. And if I want to prioritize "a" while he is loading y, he should abandon loading y and z and start to load "a", after which he may resume loading of y and then z.

 

Do you have any idea how to handle this? Any help would be appreciated. For the record I am debuging it with flash professional cs5

 

Example:

 

import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;
import com.greensock.loading.display.*;

var queue:LoaderMax = new LoaderMax({name:"mainQueue", maxConnections:1, auditSize:false});

initqueue();

function initqueue():void
{
var fold:String="";
for (var nfold:uint=1; nfold < 6; nfold++) 
{

	if (nfold==1) 	{fold="nature"}
	if (nfold==2) 	{fold="people"}
	if (nfold==3) 	{fold="event"}
	if (nfold==4) 	{fold="sport"}
	if (nfold==5) 	{fold="other"}		


	for (var count:uint=1; count <11; count++) 
	{
		queue.append( new ImageLoader("img/"+fold+"/"+count+".jpg", {name:nfold+""+count,  estimatedBytes:500000, /*container:this,*/ alpha:0, width:0, height:0, scaleMode:"proportionalOutside"}) );
	}

}
for (var afold:uint=5; afold > 0; afold--) 
{
LoaderMax.prioritize(afold+"10");	
LoaderMax.prioritize(afold+"2");	
LoaderMax.prioritize(afold+"1");
}
//queue.load();
}

Link to comment
Share on other sites

Sure, all you need to do is set the "loadNow" parameter of prioritize() to false. Like:

 

LoaderMax.prioritize(afold+"1", false);

 

By default, when you prioritize something it assumes you want it to load now but it's easy to alter that behavior :)

 

Does that answer your question?

Link to comment
Share on other sites

Wow thats great. I still got some Problems, but I'll try to solve them on my own first.

 

Just to be sure: When is do prioritize(a) then prioritize(B), b will be loaded before a, because it was moved on top of the queue after a, therefore it is higher.

 

About the way prioritize works default: I would reconsider, and set the default to "false". (But yeah, I don't see the full picture like you do).

For me, a typical use would be: Prioritize something, it should be loaded as ->fast<- as possible. When maxConnections:2, it will be loading 3 thing simultaneously after prioritizing 1 thing, or n+prior things. So actually it will load them slower then possible.

However, it might be a good thing in most cases not to abort something that is already loading, which you don't when using the default. So yeah, you are probably right.

Link to comment
Share on other sites

Just to be sure: When is do prioritize(a) then prioritize(B), b will be loaded before a, because it was moved on top of the queue after a, therefore it is higher.

 

Yes.

Link to comment
Share on other sites

Ok, I just found out that I additionally have to pause the queue before I prioritize, to avoid it being loaded instantly (and to avoid 10 images to load at the same time if reordering the whole queue)

after the priorization i can resume the queue.

 

Now after the loader works perfectly, I have another question. Maybe you could help?

 

As i said before, I am loading pictures for a portfolio. So after the loading i want to display them.

Until now (before using your great loader) I used a fl.container.UILoader to display the pictures. I would just fade to black, change the url, and fade in. I could easily resize the loader, and it would scale for every picture displayed.

 

Now I found your ContentDisplay, which looks great. However, if I understand correctly I wont be able to change it's size and position in order to scale each picture.

It just Displays the loaded picture on the coordinates i can set in the loader for each picture.

The Problem is: After i initialized the queue, it is perfectly possible that the user changes the size of the flash movie, after which i need to rescale the pictures. And thus I would need to change the properties of each ImageLoader (50).

 

1) Maybe there is a way to load all the images in just one ImageLoader? (Dont think so)

2) Can I pass the content of the loader to the fl.containers.UILoader? (When i just set the url to the same url, he will load the picture again as soon as i set the path on the UILoader)

3) Can I somehow Scale the ContentDisplay in order to scale all what will get displayed?

 

Any solution would be very helpful, and if I am doing something completely wrong, please tell me.

Link to comment
Share on other sites

Sure, just set a width/height in your vars object and that tells the ContentDisplay to honor a specific size. Set the scaleMode to whatever you want (read the docs for all the options). But then you can resize the ContentDisplay to your heart's content and it should still fit things perfectly in there. Give it a shot - I think you'll like it.

Link to comment
Share on other sites

Okay, after some hours trying and reading I made it work.

Thank you very much for your help, it is indeed really nice! The pictures are now much smoother than ever, the loading can be adjusted, the liquid layout i programed myself is now mostly obsolete.

 

But one thing still remains:

When the user enters a new folder, the pictures get prioritized in the most probable viewing order, means 1,2,3,...,10.

That works perfectly!

However, if I then want to display picture 10 after picture 1 (means: user wants to view the pictures in a backwards order), it would still load 2,3,...,9 before loading 10. This means a long wait on slow connections.

Now the best solution I can thing of would be to

onNextPictureDisplay(){

1: determine picture to display

2: check if picture is already being loaded

3: if not being loaded, abort all loading, prioritize the picture, then resume all loading

4: display transition to the new picture

}

the problem is, i found no way of doing step 2.

the real problem is: When I prioritize a picture while it is loading, it gets loaded twice. when i prioritize the same picture 10 times in a row, while it is being loaded, it gets loaded 10 times. Which makes it really slow of course.

Is there any solution?

 

(another small question: when i get the ContentDisplay to change the picture, I have to initialize some settings because they get lost/overwritten by the new picture. is there a nicer way to do that, or is it just the way it is supposed to work?)

gsimage=LoaderMax.getContent(nfold+""+imageCounter);
setChildIndex(gsimage,0);
gsimage.width=standardwidth*MAXscale;
gsimage.height=standardheight*MAXscale;
gsimage.x=(stage.stageWidth-gsimage.width)/2;
gsimage.y=(stage.stageHeight-gsimage.height)/2;	
gsimage.visible=true;

Link to comment
Share on other sites

When I prioritize a picture while it is loading, it gets loaded twice. when i prioritize the same picture 10 times in a row, while it is being loaded, it gets loaded 10 times. Which makes it really slow of course.

Is there any solution?

 

Um, I'm pretty sure that's not accurate. I just did some testing to double-check and if you prioritize() a loader while it is in the process of loading, it does NOT load it again (multiple times). What makes you think that's happening?

 

If you want to check the status of a loader (to see if it's loaded, loading, failed, etc.) just check it's "status" property, like:

if (loader.status == LoaderStatus.LOADING) {

} else if (loader.status == LoaderStatus.COMPLETED) {

} ...and so on...

 

The whole point of the prioritize() method is to accomplish the very thing you're trying to do - if you have a queue of loaders running and then you suddenly need to prioritize one, all you need to do is prioritize() it - no need to manually pause() your queue, wait for the prioritized one to load, then resume(), etc. - it's all automatic.

Link to comment
Share on other sites

Thank you very much! I'll eat dinner, try out, and report back asap!

 

Dinner was fine, results:

 

The follwing code:

 

import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;
import com.greensock.loading.display.*;

var queue:LoaderMax = new LoaderMax({name:"mainQueue", maxConnections:1, auditSize:false});

initqueue();

function initqueue():void
{

queue.append( new ImageLoader("img/nature/1.jpg", {name:"1",  estimatedBytes:500000, /*container:this,*/ alpha:0, width:0, height:0, scaleMode:"proportionalOutside"}) );
queue.append( new ImageLoader("img/nature/2.jpg", {name:"2",  estimatedBytes:500000, /*container:this,*/ alpha:0, width:0, height:0, scaleMode:"proportionalOutside"}) );


queue.load();
LoaderMax.prioritize("1",false);
LoaderMax.prioritize("2",false);
LoaderMax.prioritize("1",false);
LoaderMax.prioritize("2",false);
LoaderMax.prioritize("1",false);
LoaderMax.prioritize("2",false);
LoaderMax.prioritize("1",false);
LoaderMax.prioritize("2",false);
LoaderMax.prioritize("1",false);
}

 

1. Sets up the queue

2. Starts the queue

3. prioritizes "1" and "2" alternatively

 

With the flash debugger of cs5, "simulate download" it shows that after this code he is loading both "1" and "2" multiple times.

It could be that he just doesnt show each stream multiple times, but the loading speed difference is noticably, which means he is really loading it multiple times.

Maybe the bug is with the debugger "simulate download" thing. Maybe I ought to try it out with a browser, debugging.

 

Thanks for explaining how I can check the Status, sorry for me being unable to find out.

I will implement the solution with the Status for the time being.

Link to comment
Share on other sites

Ok, the workaround with checking the status did not work.

 

Which led to the following conclusion: The problem is ultimatevly, that when I only allow 1 Connections, he should actually cancel whatever he is loading, which he thinks he does, but it doesnt!

Thus, the first prioritized status gets set to 0 when the second wants priorisation. BUT it doesnt stop the actual loading! Then, when I want to prioritize the first one again, it thinks it isnt loading (because status=0) and it starts to load the second time.

 

If I set maxConnections to 2 in the above Example, everything works perfectly. The problem is: That isnt ultimately a solution, because I could do the same trick with 3 different items, or 4...

Also, I want to use only one connection, because I really want to get that picture loaded asap.

 

(On a side note: I think there should be 2 different methods: one to prioritize, and one to change the queue order. They are actually not always the same thing. But anyways, I am really excited about what you provide here!)

Link to comment
Share on other sites

Aha! I see the issue now - it didn't show itself unless maxConnections was 1, like you said. I just posted a revised version of the classes that should fix the issue. Please take a peek and let me know if it works well for you. http://www.LoaderMax.com

Link to comment
Share on other sites

Ok, it is even odder now ;)

 

The portfolio was still not working, and I just spent some hours trying to isolate the cause and reproduce it in a smaller application.

 

I adjusted the former application, now it has a display() function which displays the image passed as argument.

display() will prioritize the image, load it into the ContentDisplay, and blend it in.

 

Every 200ms i call display("2"); this does not result in the image being loaded multiple times! Everything perfect until now.

But if i call display("2") because of a MouseEvent.Click, it starts to load the picture multiple times, if it is still loading.

 

I added two buttons, "left" and "right", this is needed to make the example work.

 

import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;
import com.greensock.loading.display.*;
import com.greensock.*;

var queue:LoaderMax = new LoaderMax({name:"mainQueue", maxConnections:1, auditSize:false});
var loadTimer:Timer = new Timer(200,0);
var gsimage:ContentDisplay;

loadTimer.addEventListener(TimerEvent.TIMER,function(event:TimerEvent)	{display("2");}	);

initqueue();

function initqueue():void
{	

for (var count:uint=1; count <11; count++) 
	{
		queue.append( new ImageLoader("img/nature/"+count+".jpg", {name:count.toString(), container:this, alpha:0, visible:false, width:1500, height:1000, scaleMode:"proportionalOutside"}) );
	}

for (var count2:uint=1; count <11; count++) 
	{
		LoaderMax.prioritize("img/nature/"+count2+".jpg");
	}

queue.load();
loadTimer.start();
}

function display(x:String):void 
{	
	LoaderMax.prioritize(x,false);

	gsimage=LoaderMax.getContent(x);
	setChildIndex(gsimage,0);
	gsimage.x=(stage.stageWidth-gsimage.width)/2;
	gsimage.y=(stage.stageHeight-gsimage.height)/2;	
	gsimage.visible=true;

	TweenLite.to(gsimage, 1, {alpha:1});
}

right.addEventListener(MouseEvent.CLICK, click_rightstep);

function click_rightstep(event:MouseEvent):void
{
//TweenLite.to(gsimage, 0.3, {alpha:0});
display("2");
}

left.addEventListener(MouseEvent.CLICK, click_leftstep);

function click_leftstep(event:MouseEvent):void
{
//TweenLite.to(gsimage, 0.3, {alpha:0});
display("1");
}

Link to comment
Share on other sites

There were a few problems with your code that could cause some odd behavior (like you used "count" instead of "count2" in a few places and you set the child index of the new image to 0 instead of numChildren-1), but there was also a change I needed to make to the prioritization logic in LoaderMax so that it would ignore the loading routine for the prioritized loader if it was already loaded. The new version has been posted at http://www.LoaderMax.com. So to be clear, the issue would only show itself in a very particular scenario where you prioritized a loader that was already loaded and the next loader in the queue was in the process of loading.

Link to comment
Share on other sites

Thanks for your effort!

I tried it out, didn't work.

 

I removed some code, so now it only is:

 

import com.greensock.loading.*;
import com.greensock.events.LoaderEvent;
import com.greensock.loading.display.*;
import com.greensock.*;

var queue:LoaderMax = new LoaderMax({name:"mainQueue", maxConnections:1, auditSize:false});
var loadTimer:Timer = new Timer(200,0);
var gsimage:ContentDisplay;

loadTimer.addEventListener(TimerEvent.TIMER,function(event:TimerEvent)	{display("2"); display("1");}	);

initqueue();

function initqueue():void
{	

for (var count:uint=1; count <11; count++) 
	{
		queue.append( new ImageLoader("img/nature/"+count+".jpg", {name:count.toString(), container:this, alpha:0, visible:false, width:1500, height:1000, scaleMode:"proportionalOutside"}) );
	}
queue.load();
loadTimer.start();
}

function display(x:String):void 
{	
LoaderMax.prioritize(x,false);
}

 

Sorry for the mistakes in the last code (altough i dont understand the problem with the child index, nevermind).

It seems I was tired. The above code downloads each image multiple times, at least on my computer and with the "simulate download" option.

 

Note: You don't have to bother, I might just deal with it with keeping some sort of array that tells me which is already prioritized, to avoid the problem.

But maybe it's a bug affecting more people.

Link to comment
Share on other sites

That's an extremely unrealistic scenario, but yes, it appears to be a bug in Adobe's bandwidth profiler mode or Flash itself, not LoaderMax.

Link to comment
Share on other sites

Ok, thank you very much for you time.

I encounter it because I have manual controls for switching the pictures, and I prioritize upon switching the pictures. So if a user selects a, then switches to b, then to a again, without waiting for the loading to finish, a gets loaded twice.

Link to comment
Share on other sites

According to all my research, there is a known bug in the Flash "simulate download" feature that prevents the close() method of Loader from working properly, but it works fine online. Again, it's just a bug in the authoring environment, so you should be fine in your real app.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×