Jump to content
GreenSock

Gabums

External swf and tweening timing

Recommended Posts

Hello all,

 

I'm having a strange timing issue in my flash movie. I created some animations in After Effects and exported them as swfs. Then I set up code to load them in externally in my main movie. Here is an example of how I did one of them:

 

//add title
var title_loader:Loader = new Loader();
// URLRequest points to your external SWF
var SWFtitle:URLRequest = new URLRequest("title_mask.swf");
//create the container Movie Clip to load swf
var swf_title:MovieClip= new MovieClip();
title_loader.load(SWFtitle);
//just add the loaded swf to container
swf_title.addChild(title_loader);
//add container to the stage and make it visible
title_mask.addChild(swf_title);

 

The problem is, when I test the movie on my computer it works fine, but when I put it up on the server or even send the swf to another computer, the timing gets all wacky. External swfs will get jumpy and then throw the timing off of the rest of the elements. Both my main movie and my external swfs from AE are 30 fps. I also set up code on a loader swf that will let my main swf play ONLY after all the rest of the swfs are loaded. Maybe I wrote that code wrong and thats why some of the swfs skip around?

 

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

var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler});

queue.append(new SWFLoader("main.swf", {autoPlay:false}));
queue.append(new SWFLoader("snowfall.swf", {autoPlay:false}));
queue.append(new SWFLoader("plane_lg.swf", {autoPlay:false}));
queue.append(new SWFLoader("title_mask.swf", {autoPlay:false}));

//begin loading
queue.load();

function progressHandler(event:LoaderEvent):void
{
   var pcent:Number=event.target.progress*100;
   lbar.scaleX=pcent/100;
   lbc.text=int(pcent)+"%";
if(pcent == 100){
gotoAndPlay(2);  //this line takes you to the next frame where my main swf gets loaded in and plays
}
}

 

I am also using timelineMax and tweenMax...maybe sprinkled in with a little of the Lite versions. Would this be the cause of the adverse effects? Do I need to pick a type and stick with it, or do they mix and match ok? Any ideas or tips would be greatly appreciated.

Thank you!

Link to comment
Share on other sites

I am also using timelineMax and tweenMax...maybe sprinkled in with a little of the Lite versions. Would this be the cause of the adverse effects?

 

no.

 

as for the rest of your problems its difficult to diagnos without seeing anything thing. It is possible that your AE swfs are very complicated and are causing some processor lag. TweenLite and its siblings always accurately render their animation based on how much time has elapsed. so if your AE swfs cause a 2 second lag, the TweenLite animations will render their animations as they should appear 2 seconds into the animation.

 

I don't really understand your setup of loading 5 swfs with LoaderMax and then going to another frame and loading the main swf, but perhaps there is a good reason. Your LoaderMax code looks fine... you could remove the if(pcnt = 100) and just have an onComplete callback... but that isn't a big deal.

 

Again, its hard to really definitively give any advice without seeing what is happening or knowing more about the assets you are loading.

Link to comment
Share on other sites

Thank you so much for taking the time to answer my questions. Here is a test link that shows the issue.

 

http://www.inspiredbynight.com/holiday/

 

It basically starts when the title of the animation comes in, it looks like it hesitates briefly and then throws everything else off. I know that my swfs built in AE are fairly large (about 2 mb) so I wanted to make sure that all my swfs were loaded in advance before I played the main movie. Which is why I have a separate file to make sure all is loaded before the main movie plays. Here is the code for when my plane comes in:

 

var TimeLinePlane:TimelineMax = new TimelineMax();
TimeLinePlane.append(new TweenLite(plane_lg_swf, 3, {x:-470, y:-40, scaleX:.5, scaleY:.5, onCompleteParams:["plane1"]}));
TimeLinePlane.append(new TweenLite(plane_lg_swf, 3, {x:-1600, y:20, scaleX:1, scaleY:1, onCompleteParams:["plane2"]}));
TimeLinePlane.append(new TweenLite(plane_lg_swf, 5, {delay:1, x:100, y:100, scaleX:.15, scaleY:.15, onCompleteParams:["plane3"]}));
TimeLinePlane.append(new TweenLite(plane_lg_swf, 5, {delay:5, x:-100, y:-100, scaleX:.1, scaleY:.1, onCompleteParams:["plane4"]}));

 

Perhaps it is reading the delay or the speed differently on different computers???

 

so if your AE swfs cause a 2 second lag, the TweenLite animations will render their animations as they should appear 2 seconds into the animation.

 

If the above is the case, is there a way to make my animations appear 2 seconds later to compensate for the 2 second lag?

 

Thank you again!

Link to comment
Share on other sites

that's a very cool animation. nice work.

 

unfortunately, I wasn't able to really notice what you meant by lag. perhaps things are out of sync and I just don't know what to look for.

 

It is extremely unlikely that the delays are getting read differently on different computers. if you try to offset your animation to compensate for processor lag it is never going to be consistent or accurate.

 

something tells me those AE swfs aren't very well optimized as I can't image how so few vector shapes can take so long to download. Again, my guess is that the frame to frame rendering is choking and not keeping up with your tweens. I really do like the look and feel of everything.

 

c

Link to comment
Share on other sites

I think there's a lot more going on than meets the eye with your project. I didn't have time to look at things in-depth, but here are some things I noticed:

 

1) You've got some null object reference error on your main timeline. My Flash debugger choked on it. So there's a problem with your code somewhere.

 

2) Your swfs are huge. plane_lg.swf is about 3MB, title_mask.swf is about 2MB, snowfall.swf is about 1.5MB, and main.swf is 387k. It looks like your AE animations are being rasterized into pngs internally, NOT vectors. Not that it's wrong or anything, but just to have that propeller spinning, AE is creating a new png for every frame and there's tons of redundant data in there. Imagine if a 50x50 area changes (the spinning blades), it's still rasterizing the entire 2380x600 area. That's a ton of wasted pixels that Flash has to load and render.

 

3) Why do you have onCompleteParams in your tweens but no onComplete? That won't do anything - it's wasted space.

 

4) If you want the tweens to by frames-based so that when the player lags (fails to maintain the frame rate), you can do that by setting useFrames:true in your tweens (or if you're putting them into a TimelineLite/Max, set that special property on the TimelineLite/Max's vars).

 

Hope that helps at least a little. You might need a high-level Flash guru to rework and optimize your project. It's probably beyond the scope we can provide here on a casual basis.

Link to comment
Share on other sites

Thank you so much both of you for your kind words and help. I just downloaded a debugger for my flash projects since I had never used one before. I'm looking into that null object now. I know my swf files are huge, I was hoping that loading them first before playing would solve any lag time issues. I suppose not. I did switch some of the animations to be frame based and I see a huge difference in keeping the animations together. When I get a chance, I'm going to see about doing something like making just the propeller in AE and the rest vector. Perhaps that will help things along. For now though, I have a insanely ridiculous deadline of Friday to finish the rest of this up so I'll have to optimize later. Thank you again for your advice and recommendations. I'll be sure to post back if I get it resolved or not :)

Link to comment
Share on other sites

  • 3 weeks later...

Hello again,

 

I have another question about this now that I'm looking over my code some more. So I have the loader set up:

 

var queue:LoaderMax = new LoaderMax({name:"mainQueue", onProgress:progressHandler});
queue.append(new SelfLoader(this, {name:"self", estimatedBytes:459403, autoPlay:false}));
queue.append(new SWFLoader("snowfall.swf", {name:"snowfall", estimatedBytes:1324144, autoPlay:false}));
queue.append(new SWFLoader("banner.swf", {name:"banner", estimatedBytes:461226, autoPlay:false}));
queue.append(new SWFLoader("plane_lg.swf", {name:"plane_lg_swf", estimatedBytes:349347, autoPlay:false}));
queue.append(new SWFLoader("title_mask.swf", {name:"title_mask", estimatedBytes:2202010, autoPlay:false}));

//begin loading
queue.load();

 

And then in order to have the swf play sometime in the future I have code such as this:

 

var title_loader:Loader = new Loader();
var SWFtitle:URLRequest = new URLRequest("title_mask.swf");
var swf_title:MovieClip = new MovieClip();
title_loader.load(SWFtitle);
swf_title.addChild(title_loader);
title_mask.addChild(swf_title);

 

The thing that is confusing me, and it all seems to be working fine I'm just trying to understand, when I set up the new URLRequest, aren't I calling the swf that isn't already loaded??? I mean, shouldn't I find a way to call my loaded swf from the loadermax --- ie - the name "title_mask" --- instead of calling the external swf itself. It would seem to me that this line:

var SWFtitle:URLRequest = new URLRequest("title_mask.swf");

is not utilizing the fact that I have already preloaded the swf. Does this make sense? Am I doing this wrong or am I just over thinking this?

 

Thanks again!

Link to comment
Share on other sites

yeah, you probably don't want to be using a Loader object when you already have everything handled with LoaderMax and SWFLoaders.

 

to target and play a swf that was loaded by a SWFLoader you can do:

 

 

 

LoaderMax.getLoader("title_mask").rawContent.play();

 

 

and to place it on the stage:

 

addChild( LoaderMax.getContent("title_mask") );

Link to comment
Share on other sites

Hmmm, I thought it would be something like that. I am getting an error though:

 

Error #1069: Property play not found on flash.display.Loader and there is no default value.

 

After looking through the forums some more, I found that someone else had that issue but it was resolved with them changing the AS code from 2 to 3. All of my swfs are in AS3 so that's not the problem. It was mentioned that there might be an issue with not having a crossdomain.xml file. Looking into what that is, it seems like that is for if your swfs are coming from different domains which mine are not. They are all on the same server in the same folder. Very confused :(

 

If I change the code to this:

 

LoaderMax.getLoader("title_mask").rawContent;
title_show.addChild(LoaderMax.getContent("title_mask"));
title_show.play();

 

It loads BUT the swf has already been completed and you don't see the animation. So it ignored the "autoplay:false" command in the loadermax. Very grrr :(

 

Update - I just uploaded a crossdomain.xml file to my server and it is still not working... so that is probably not the issue then...right?

Link to comment
Share on other sites

this issue seems to be getting a bit confused.

 

I mentioned telling the rawContent of the SWFLoader to play:

 

LoaderMax.getLoader("title_mask").rawContent.play();

 

and now you are telling title_show to play:

 

title_show.play();

 

from looking at your code, I don't see any previous reference to title_show

 

Also, are you waiting for the swf to be fully loaded before telling it to play?

 

please look at the attached example files. the code looks like this:

 

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

var queue:LoaderMax = new LoaderMax({name:"main"});

queue.append( new SWFLoader("loadSingleSwf_child.swf", {onComplete:childComplete, autoPlay:false}));

queue.load()


function childComplete( e:LoaderEvent ):void{

trace("child swf is loaded");
//you can access the content and raw content through the LoaderEvent
trace("the loader is " + e.target);
trace("the content is " + e.target.content);
trace("the actual swf is " + e.target.rawContent);

trace("\n or you can access the content through LoaderMax.getLoader().content " + LoaderMax.getLoader("loadSingleSwf_child.swf").content);
trace("\n or you can access the content through LoaderMax.getContent() " + LoaderMax.getContent("loadSingleSwf_child.swf"));

trace("\n and you can access the swf through LoaderMax.getLoader().rawContent) " + LoaderMax.getLoader("loadSingleSwf_child.swf").rawContent);


var LoaderContent:ContentDisplay = LoaderMax.getContent("loadSingleSwf_child.swf");
LoaderContent.x = 50;
LoaderContent.y = 120;


//to see the SWFLoaders content (ContentDisplay object that holds the swf)
addChild(LoaderContent);

//to have the swf play 
LoaderMax.getLoader("loadSingleSwf_child.swf").rawContent.play();


}

Link to comment
Share on other sites

Thank you for bearing with me...I'm sorry to be going all over the place here. I'm just trying any option I can think of and I guess it's becoming a mess. What I would like to do, and you are correct in your assumption, is load all my swfs and then later on, call an individual loaded swf to play. I already have empty movie clips made to put the loaded swfs in. This is where the "title_show" came in. So I took your previous code and changed it to this:

 

LoaderMax.getLoader("title_mask").rawContent.play();
title_show.addChild(LoaderMax.getContent("title_mask"));

 

(BTW - I changed the empty SWF to be called "title_show" instead of "title_mask" like I did in my previous posts since I thought it would be easier to tell what I was referring to this way)

 

I see what you did with the code and I think I understand how it works, but it brings me back to my question at hand. You have this code:

 

var LoaderContent:ContentDisplay = LoaderMax.getContent("loadSingleSwf_child.swf");
addChild(LoaderContent);
LoaderMax.getLoader("loadSingleSwf_child.swf").rawContent.play();

 

Doesn't that do the same as this?

 

var title_loader:Loader = new Loader();
var SWFtitle:URLRequest = new URLRequest("title_mask.swf");
var swf_title:MovieClip = new MovieClip();
title_loader.load(SWFtitle);
swf_title.addChild(title_loader);
title_show.addChild(swf_title);

 

Both codes are not utilizing the already loaded swf correct? Your code calls "loadSingleSwf_child.swf" and mine calls "title_mask.swf"?? I attached a sample fla to show you what I'm working with. My code on the second frame has different versions that are commented out. If you un-comment them, you can see the errors I am getting.

 

I really really appreciate your time with this. Thank you!

Link to comment
Share on other sites

can't open your file. please save it down to CS4.

 

the whole point of using LoaderMax and SWFLoader is so that you don't have to use:

 

var title_loader:Loader = new Loader();
var SWFtitle:URLRequest = new URLRequest("title_mask.swf");
var swf_title:MovieClip = new MovieClip();
title_loader.load(SWFtitle);
swf_title.addChild(title_loader);
title_show.addChild(swf_title);

 

Both codes are not utilizing the already loaded swf correct?

 

no. my code is waiting for the swf to load, placing it on the stage and telling it to play. your code is not waiting for the swf to load, nor is it telling it to play.

 

Your code calls "loadSingleSwf_child.swf"

yes, that is the name of the swf I am loading.

Link to comment
Share on other sites

Sorry about that. Attached is the cs4 version. I think I see what you mean now, but I still can't seem to get it to run correctly. Even when I get it to load and play, it still ignores my "autoplay:false" command and plays before I even tell it to.

Link to comment
Share on other sites

thanks for converting the file and commenting your progression so well.

 

the code that you had looked good and like you were implementing my suggestions correctly.

 

Are you ABSOLUTELY certain that title_mask2.swf is an AS3 swf?

 

I opened your file, tested, and got errors about the Loader thing.

 

I created my own swf called carl.swf and changed the code to load carl.swf instead of title_mask2.swf.

 

it worked fine. ?

 

see the attached.

Link to comment
Share on other sites

Hmmm that is really odd. Your animation worked for me as well. I guess I am not 100% positive the swfs are AS3. They were exported from After Effects (which is why they are so large and I'm loading them externally in the first place). I'll have to look into it some more. It is strange that AE 5.5 would export swfs in AS2 when AS3 is the new thing. Is there a work around if the swf's are AS2?

 

Once again, I really really appreciate you taking the time to work on this with me.

Thanks!

 

UPDATE - I got it to work finally!!! I ended up taking my exported swf from After Effects and bringing it into flash, saving it as AS3. The code you provided me is now working perfectly. Thank you again for your time and patience!!!

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.
×